1

Let us assume that we have a JPEG file of mushrooms given in the following link: WIKI MUSHROOMS

To make it easier to find the desired points in the JPEG, Let us draw a labeled grid on top of the image following the answer of Jake at the link below: Jake Label Grid on Top of JPEG Following Jake answer we define a coordinate system having its (0,0) at the southwest and (1,1) at the northeast of the JPEG. Let us assume that we want to add a rounded rect node at the scaled (0.5, 0.5) of the JPEG with the inner xsep= 0.2 unit and inner ysep= 0.2 scaled unit. Below is my code:

\documentclass{standalone} 
\usepackage{tikz}
\usetikzlibrary {shapes.misc}
\usepackage{anyfontsize}
\newcommand{\midfont}{\usefont{T1}{cmr}{b}{n}\fontsize{15}{\baselineskip} \selectfont}
\begin{document} 
\begin{tikzpicture}
\node[anchor=south west,inner sep=0] (image) at (0,0) {\includegraphics[width=0.9\textwidth] 
{mushrooms.jpg}};
\begin{scope}[x={(image.south east)},y={(image.north west)}]
    \draw[help lines,xstep=.1,ystep=.1] (0,0) grid (1,1);
    \foreach \x in {0,1,...,9} { \node [anchor=north] at (\x/10,0) {0.\x}; }
    \foreach \y in {0,1,...,9} { \node [anchor=east] at (0,\y/10) {0.\y}; }
\node at ( {.5+0},.5) [ red, line width=2 pt, shape=rounded rectangle,draw, inner xsep=30, 
inner ysep=20] (rect){};
\node at ( {.5-.2},{.5+.2}) (text){\textcolor{red}{\midfont{Center is Here}}};
\draw [line width=3 pt, red][->] (rect) -- (text);
\end{scope}
\end{tikzpicture}
\end{document}

I have two questions as below:

  1. What is the meaning of [x={(image.south east)},y={(image.north west)}] after scope declaration?
  2. I wanted to use 0.2 scaled unit for inner x sep and y sep to span my rounded rect node 0.2 unit along x and .2 unit along y. but in order to do that I had to use inner xsep=30, inner ysep=20. I did it by trial and error. Is there any more accurate way to get the correct values of inner xsep and ysep to obtain exactly 0.2 scaled unit for both x and y direction for the rect node? result

2 Answers 2

2

x={(image.south east)}, y={(image.north west)} in the optional argument of scope defines the /tikz/x and /tikz/y unit vectors within the given scope so that, in the low-level PGF drawing system:

  • the x coordinate of /tikz/x is the width of the image in points and its y coordinate is 0pt;

  • the x coordinate of /tikz/y is 0pt and its y coordinate is the height of the image in points.

This works because the preceding code:

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

defined image as a tight rectangular node around the image, whose south west corner has been placed at the origin (0,0).

Regarding what you want to achieve, most TikZ options that expect a length interpret a unitless input as a length in points, which is why you had to use trial and error and give “large” values to inner xsep and inner ysep. I'd rather use the minimum width and minimum height options to determine the desired width and height for the rect node. One still needs to either give them with explicit units, or provide the lengths in points. I'll use simple \getxlength and \getylength macros to allow easy storing of the current lengths of the /tikz/x and /tikz/y vectors, expressed in points (other techniques can be found in the answers to this question).

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc, shapes.misc}

\newcommand{\midfont}{\fontsize{15}{18}\usefont{T1}{lmss}{m}{n}}

\makeatletter
% These assume that the /tikz/x vector is “horizontal” and /tikz/y “vertical”.
\newcommand*{\getxlength}[1]{\edef#1{\the\pgf@xx}}
\newcommand*{\getylength}[1]{\edef#1{\the\pgf@yy}}
\makeatother

\begin{document}

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

\begin{scope}[x={(image.south east)}, y={(image.north west)}]
  \draw[help lines, xstep=.1, ystep=.1] (0,0) grid (1,1);
  \foreach \x in {0,1,...,9} { \node [anchor=north] at (\x/10, 0) {0.\x}; }
  \foreach \y in {0,1,...,9} { \node [anchor=east] at (0, \y/10) {0.\y}; }

  % Get the unit vector lengths in points
  \getxlength{\xLen} \getylength{\yLen}
  \node[draw, red, line width=1pt, shape=rounded rectangle, inner sep=0,
        minimum width=0.2*\xLen, minimum height=0.2*\yLen]
     at (.5,.5) (rect) {};
  \node[red, font=\midfont] at (0.5-0.2, 0.5+0.2) (text) {Center is here};
  \draw[line width=1pt, red, ->] (text) -- (rect);
\end{scope}
\end{tikzpicture}

\end{document}

enter image description here

4
  • 1
    I highly appreciate your care dear frougon and the time you spent to write such a very instructive and excellent answer. Thank you so much!
    – Aria
    Aug 10, 2021 at 3:34
  • Thanks again. Two questions: 1)What is the meaning of \the and \pgf@xx in \edef#1{\the\pgf@xx} 2) In which CTAN package we can find the explanation of \the and \pgf@xx in \edef#1{\the\pgf@xx}?
    – Aria
    Oct 9, 2021 at 19:38
  • First, you need to read the TikZ & PGF manual on coordinate systems (p. 137 for version 3.1.9a). The xyz coordinate system allows one to define points using a linear combination of three base vectors called x, y and z. \pgf@xx is a ⟨dimen⟩ register (more precisely, a ⟨dimendef token⟩) that says how much the x vector points to the right, \pgf@xy says how much the x vector points upwards, ... \pgf@yy says how much the y vector points upwards. ⟨dimen⟩ registers are TeX registers that contain rigid lengths.
    – frougon
    Oct 10, 2021 at 21:39
  • 1
    \the followed by a ⟨dimendef token⟩ expands to a string which is the length contained in the corresponding ⟨dimen⟩ register, in points. ⟨dimen⟩ registers, ⟨dimendef tokens⟩ and \the are explained in the TeXbook.
    – frougon
    Oct 10, 2021 at 21:41
1
  1. [x={(image.south east)},y={(image.north west)}] defines the x-vector and y-vector in the scoped coordinate system.

  2. inner sep parameter (as inner xsep and inner ysep) is an absolute length. Its default unit is pt. So inner xsep=30 is equivalent to inner xsep=30pt.

    To define a node with your requirements, you can use the calc and fit libraries.

    Note: the rounded parts of the rounded rectangle shape can't contain text (look at the differences between the red and the orange nodes).

enter image description here

\documentclass{standalone} 
\usepackage{tikz}
\usetikzlibrary {shapes.misc,fit,calc}
\usepackage{anyfontsize}
\newcommand{\midfont}{\usefont{T1}{cmr}{b}{n}\fontsize{15}{\baselineskip} \selectfont}
\begin{document} 
\begin{tikzpicture}
  \node[anchor=south west,inner sep=0] (image) at (0,0) {\includegraphics[width=0.9\textwidth] 
    {Mycena_interrupta.jpg}};
  \begin{scope}[x={(image.south east)},y={(image.north west)}]
    \draw[help lines,xstep=.1,ystep=.1] (0,0) grid (1,1);
    \foreach \x in {0,1,...,9} { \node [anchor=north] at (\x/10,0) {0.\x}; }
    \foreach \y in {0,1,...,9} { \node [anchor=east] at (0,\y/10) {0.\y}; }
    %\node at ( {.5+0},.5) [ red, line width=2 pt, shape=rounded rectangle,draw, inner xsep=30pt,inner ysep=20pt] (rect){};
    \node[fit={($(.5,.5)+(.2,.2)$)($(.5,.5)+(-.2,-.2)$)},shape=rounded rectangle,draw=red,inner sep=0,line width=2pt](rect){};
    \node at ( {.5-.3},{.5+.3}) (text){\textcolor{red}{\midfont{Center is Here}}};
    \draw [line width=3 pt, red][->] (text) -- (rect);
    \node[fit={($(.5,.5)+(.2,.2)$)($(.5,.5)+(-.2,-.2)$)},shape=rectangle,draw=orange,inner sep=0]{};
  \end{scope}
\end{tikzpicture}
\end{document}
1
  • Thank you Mr. Paul for the good answer. Appreciate your care.
    – Aria
    Aug 10, 2021 at 3:35

You must log in to answer this question.

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