2

I would like to create a tikzpicture where a rectangular part is imported from a raster image (let's say a PNG), and there are other TikZ nodes on top of it. The tricky part is that I need to position the TikZ nodes with reference to pixels in the raster image.

Based on this example, we can make the space (0,0) -- (1,1) span an image. I thought it would then simply be a matter of scaling:

\documentclass[tikz]{standalone}

\usepackage{tikz}
\usepackage{mwe}

\begin{document}
\begin{tikzpicture}

\node[anchor=south west,inner sep=0] (image) at (0,0)
  {\includegraphics[width=0.9\textwidth]{example-image.jpg}};

\begin{scope}[x={(image.south east)},y={(image.north west)}]
  \begin{scope}[xscale=1/400, yscale=1/300]
    \draw[red,ultra thick,rounded corners] (200, 200) rectangle (300, 250);
  \end{scope}
\end{scope}

\end{tikzpicture}
\end{document}

Two problems with this:

  1. I'd like to avoid hardcoding the image dimensions
  2. More pressingly, this fails with the following error message:
! Dimension too large.
<recently read> \pgf@xx 
                        
l.14 ...ed,ultra thick,rounded corners] (200, 200)
                                                   rectangle (300, 250);
1

2 Answers 2

1

It's nice question. To answer both of your questions (hard to position points on the image, and Dimension too large error), I propose using different way (other than this answer - scaling matters!) as follows.

How to easily determine points on the image? Inserting the image via TikZ's node, using suitable options as you think fit, then drawing a grid for easy positioning.

Here is a situation I am drawing for fun (not yet finished) that illustrates the technique mentioned above. The point A=(Ax,Ay) and B=(Bx,By) are positioned as the bottom of V and the top of A in VAIO logo.

enter image description here

\documentclass[tikz,border=5mm]{standalone}
\usepackage{comment}
\begin{document}
\begin{tikzpicture}
%\begin{comment}
% for easy positioning points from the image
\draw[violet!20,very thin] (-3,-1) grid[step=.2] (3,1);
\draw[violet,thin] (-3,-1) grid (3,1);
\foreach \i in {-3,...,3} \path (\i,-1) node[below]{\i};
\foreach \j in {-1,0,1} \path (-3,\j) node[left]{\j};
% https://lambanner.com/y-nghia-an-logo/
\path (0,0) node[opacity=.5]{\includegraphics[width=5cm]{vaiologo.png}};
\fill[red] (0,0) circle(1pt);
% also see https://1000logos.net/vaio-logo/
%\end{comment}

% positioning by trial-and-error
% A=(\Ax,\Ay) the bottom of V
% B=(\Bx,\By) the top of A
\def\Ax{-1.45}
\def\Ay{-.48}
\def\Bx{-.48}
\def\By{.46}

% the middle of VA
\def\VAcurve{(\Ax,\Ay) .. controls +(0:.4) and +(180:.4) ..(\Bx,\By)}
% the right of VA
\def\VAcurveRight{{[shift={(\Bx,0)},xscale=-1,shift={(-\Bx,0)}]\VAcurve}}
% the left of VA
\def\VAcurveLeft{{[shift={(\Ax,0)},xscale=-1,shift={(-\Ax,0)}]\Vcurve}}
\draw[line width=2mm,red,opacity=1] \VAcurve \VAcurveRight \VAcurveLeft 
;
\end{tikzpicture}
\end{document}

With comment

enter image description here

0

For the second problem, I have found a solution by setting the coordinate system to 1/400 and 1/300 increments, and flipping the Y axis:

\node[anchor=south west,inner sep=0] (image) at (0,0)
  {\includegraphics[width=0.9\textwidth]{example-image.jpg}};

\begin{scope}[x={(image.south east)},y={(image.north west)}]
  \begin{scope}[shift={(0,1)},x={(1/400,0)},y={(0,-1/300)}]
    \draw[red,ultra thick,rounded corners] (200, 200) rectangle (300, 250);
    \draw[red,ultra thick,rounded corners] (0, 0) rectangle (100, 100);
  \end{scope}
\end{scope}

The first problem (computing the increments 1/400 and -1/300 from the picture's raster dimensions) is still an open question.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .