TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I want to draw on an image which I embedded using \includeimage:

\documentclass[tikz]{standalone}
\begin{document}
  \begin{tikzpicture}
    \node[anchor=south west,inner sep=0] (image) at (0,0) {\includegraphics{example-image}};
    \begin{scope}[x={(image.south east)},y={(image.north west)}]
      \draw[color=red] (0,0) rectangle (1,1);
    \end{scope}
  \end{tikzpicture}
\end{document}

Let's say the image has a size of 800x600 pixels. The problem here is that x and y scale between 0 and 1 in width and height. I would like to draw on the image using it's pixels as a coordinate reference, in a way that

\draw[color=red] (0,0) rectangle (1,1);

can be replaced by

\draw[color=red] (0,0) rectangle (800,600);

My problem now is to scale the x and y in the scope. I thought the following statement would work:

\begin{scope}[x={($(image.south east)/800$)},y={($(image.north west)/600$)}]

but it throws the following error:

Package tikz Error: + or - expected.

I looked up chapter 13.5 in the TikZ/PGF manual, but it seems like it is not working with the image.direction statement this way.

How can I scale my scope in the right way?

share|improve this question
    
I know vector graphics use no pixels, but I want to match the coordinate system of the embedded bitmap with the coordinate system of the vector graphics. – braxlan Feb 17 at 19:51
    
From chapter 13.5 of the TikZ/PGF manual: "The general syntax is the following: ([(options)]$(coordinate computations)$). As you can see, the syntax uses the TEX math symbol $ to indicate that a "mathematical computation" is involved. However, the $ has no other effect, in particular, no mathematical text is typeset." – braxlan Feb 17 at 20:03
up vote 4 down vote accepted

Edit: In the first version of my answer -- as pointed @Jake in his comment -- I miss the point in the question ... so here is corrected solution, inspired by @Jake answer:

    \documentclass{article}
    \usepackage{tikz}
    \usepackage{calc}
    \usepackage{graphicx}

\begin{document}
    \begin{figure}
\centering
\sbox0{\includegraphics[width=0.5\textwidth]{example-image}}%
\begin{tikzpicture}[x=\wd0/800, y=\ht0/600]
\node[anchor=south west,inner sep=0pt] at (0,0){\usebox0};
\draw[blue] (200,100) rectangle + (500,300);
\draw[red,thick] (0,0) rectangle + (800,600);
\end{tikzpicture}
    \end{figure}
\end{document}

Main difference is that instead new lengths is used box0 and possibilities which it offer. With this above code is somewhat shorter but gives equal result:

enter image description here

Addendum: Let be noted, as say @jfbu in his comment: "... \box0 is sometimes a bit dangerous especially if you delay use of \wd0 or \ht0. It is safer to do \newsavebox\mybox and use \sbox\mybox, \wd\mybox ... ". So, although till to now I haven't bad experiences with box0, it is better to stay on safe side of LateX use, and rewrite above MWE into:

\documentclass{article}
    \usepackage{tikz}
    \usepackage{calc}
    \usepackage{graphicx}

\newsavebox\mybo

% for show only a figure
\usepackage[active,floats,tightpage]{preview}
\PreviewBorder{1em}

\begin{document}   
    \begin{figure}[h]
\centering
\sbox\mybox{\includegraphics[width=0.5\textwidth]{example-image}}%
\begin{tikzpicture}[x=\wd\mybox/800, y=\ht\mybox/600]
    \node[anchor=south west,inner sep=0pt] at (0,0) {\usebox\mybox};
    \draw[blue,very thin] (200,100) rectangle + (500,300);
    \draw[red,thick] (0,0) rectangle + (800,600);
\end{tikzpicture}
    \end{figure}
\end{document}

The bots solution has important advantage: The image is processed ony ones (when storing in save box and than used as \usebox\mybox or in accordance of the first example as \usebox0. This potentially reducing compilation time (as also stated @jfbu in his comment).

share|improve this answer
    
@jake, thank you very much to pointed me to my misunderstanding of question. Now I correct my answer and reopen it. – Zarko Feb 17 at 23:34
    
Thank you! I'm fill embarrassed ... – Zarko Feb 18 at 11:29
    
\box0 is sometimes a bit dangerous especially if you delay use of \wd0 or \ht0. It is safer to do \newsavebox\mybox and use \sbox\mybox, \wd\mybox, etc... – jfbu Feb 18 at 11:37
    
maybe you could explain that this allows to use \includegraphics only once, thus potentially reducing compilation time ? – jfbu Feb 18 at 11:44

You're trying the right thing, but the coordinate calculation syntax is a bit limited: it expects the factor for stretching the vector to appear at the start of the expression. So you could use

\begin{scope}[x={($1/800*(image.south east)$)},y={($1/600*(image.north west)$)}]

However, it turns out that apparently this approach has some precision issues, with the resulting coordinate system not matching the image exactly.

So instead, you might want to use cfr's approach from http://tex.stackexchange.com/a/269850/2552, which works without problems for me (but involves more typing):

\documentclass[tikz, demo]{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}

\newlength\iwidth
\newlength\iheight
\settoheight\iheight{\includegraphics{example-image}}
\settowidth\iwidth{\includegraphics{example-image}}

  \begin{tikzpicture}[x=\iwidth/800, y=\iheight/600]
    \node[anchor=south west,inner sep=0] (image) at (0,0) {\includegraphics{example-image}};
      \draw[color=red] (0, 0) rectangle (800, 600);
  \end{tikzpicture}
\end{document}
share|improve this answer
    
This works! Interestingly the rectangle does not really fit the image... Maybe a float precision problem, or just my setup! ;) – braxlan Feb 17 at 20:06
    
@braxlan: Hm, interesting, I get the same problem. It works with 1/80 and 1/60, but not 1/800. I edited my answer to show an alternative approach that doesn't have the same problem – Jake Feb 17 at 20:30

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.