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);

Cactus
  • 1,107

2 Answers2

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

Black Mild
  • 17,569
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.

Cactus
  • 1,107