0

The LaTeX Overlay Generator is a great tool to annotate sub-images of an image in a LaTeX-caption way. It names itself "Visual Overlay Generator v0.0.1", as it creates a visual overlay: a diagram which is overlayed on the original image.

The same LaTeX Overlay Generator was the base of User f2cx's answer to the OP How can/should I include annotated images?.

However, I am looking for a different way to annotate sub-images of an image. That is:

  • They don't have to be "captions" in a Tex-sense: they can be plain text.
  • The visual overlay from the "Visual Overlay Generator" should be added on the right side of the original image (cf. the left-right layout in the example images below for better understanding ... alternatively they can be top-bottom sometimes, when one is dealing with "wide" images).
  • The text of the captions should be added within the visual overlay, rather than below the original image.

Let's take the following image (containing sub-images) as an example (the different sub-images are represented by different colours, just as an example):

Image with sub-images

Then, the following is what I would like to end up with (the original image on the left, and an annotation-diagram on the right, where captions can be added via Tex in the center of each box in the annotation-diagram):

Image on the left, and annotation-diagram with captions on the right

Although, I personally think it doesn't aid the clarity of the caption-diagram, the following could be an optional variant of that, where the right side also features the original image as a background (with an opacity of ±20%):

Variant with original image as background, with low opacity

I have no clue of an elegant way to achieve this in Tex. Perhaps it could be (sped up) possible with the help of a GUI, such as a vector image creator (e.g. GIMP, Inkscape, Adobe Illustrator, ...)? The "overlay"-annotation-diagram could then be traced easily in such a software, and the diagram could then be exported as a SVG. Unfortunately, I do not know how one could then use Tex to annotate (write actual comments) the different "objects" (read: rectangles representing sub-images in the diagram), e.g. in the center of each "object" (read: rectangle).

Any advice (for sticking with Tex to achieve the result, or if not: avoiding it) or a workable solution please? I will need this process to create many (more than 100) images.

2

So, the custom code generated from LaTeX Overlay Generator can be used and altered minimally in the following way:

  • \node at (#4) should be replaced by \node at ($ (#1)!.5!(#2) $), which will place the label in the middle of the rectangles (instead of taking an optional 4-th argument);

  • to make the previous step work, one needs to include \usetikzlibrary{calc} below \usepackage{tikz};

  • {white}{white}{black}{black} can be changed to {white}{none}{none}{black} to delete the white circle with the black border;

  • [anchor=south west,inner sep=0] (image) can be changed to [anchor=south west,inner sep=0,opacity=0.2] (image) to give a 20% opacity to the background image;

  • Presuming you had an overlay-rectangle generated with the default "code" {A}, one can change this to {the caption you'd like to give to the sub-image}.

So, imagine we want to work with the following code, generated via LaTeX Overlay Generator (I just deleted the comment lines, as well as \caption{...} & \label{fig:teaser}):

\documentclass{article}

\usepackage{graphicx}

\usepackage{tikz}

\newcommand*\annotatedFigureBoxCustom[8]{\draw[#5,thick,rounded corners] (#1) rectangle (#2);\node at (#4) [fill=#6,thick,shape=circle,draw=#7,inner sep=2pt,font=\sffamily,text=#8] {\textbf{#3}};}

\newcommand*\annotatedFigureBox[4]{\annotatedFigureBoxCustom{#1}{#2}{#3}{#4}{white}{white}{black}{black}}
\newcommand*\annotatedFigureText[4]{\node[draw=none, anchor=south west, text=#2, inner sep=0, text width=#3\linewidth,font=\sffamily] at (#1){#4};}
\newenvironment {annotatedFigure}[1]{\centering\begin{tikzpicture}
\node[anchor=south west,inner sep=0] (image) at (0,0) { #1};\begin{scope}[x={(image.south east)},y={(image.north west)}]}{\end{scope}\end{tikzpicture}}

\begin{document}

\begin{figure}[h!t]

\begin{annotatedFigure}
    {\includegraphics[width=1.0\linewidth]{qUq7A.jpg}}
    \annotatedFigureBox{0.1113,0.5114}{0.625,0.7951}{A}{0.1113,0.5114}
\end{annotatedFigure}

\end{figure}

\end{document}

Then, we adapt it (following the steps described above), to achieve (I made the image smaller by changing [width=1.0\linewidth] to [width=0.5\linewidth]):

\documentclass{article}

\usepackage{graphicx}

\usepackage{tikz}
\usetikzlibrary{calc}

\newcommand*\annotatedFigureBoxCustom[8]{\draw[#5,thick,rounded corners] (#1) rectangle (#2);\node at ($ (#1)!.5!(#2) $)[fill=#6,thick,shape=circle,draw=#7,inner sep=2pt,font=\sffamily,text=#8] {\textbf{#3}};}

\newcommand*\annotatedFigureBox[4]{\annotatedFigureBoxCustom{#1}{#2}{#3}{#4}{white}{none}{none}{black}}
\newcommand*\annotatedFigureText[4]{\node[draw=none, anchor=south west, text=#2, inner sep=0, text width=#3\linewidth,font=\sffamily] at (#1){#4};}
\newenvironment {annotatedFigure}[1]{\centering\begin{tikzpicture}
\node[anchor=south west,inner sep=0,opacity=0.2] (image) at (0,0) { #1};\begin{scope}[x={(image.south east)},y={(image.north west)}]}{\end{scope}\end{tikzpicture}}

\begin{document}

\begin{figure}[h!t]

\begin{annotatedFigure}
    {\includegraphics[width=1.0\linewidth]{qUq7A.jpg}}
    \annotatedFigureBox{0.1113,0.5114}{0.625,0.7951}{the caption you'd like to give to the sub-image}{0.1113,0.5114}
\end{annotatedFigure}

\end{figure}

\end{document}

That yields something as such (if one doesn't want the background image, one can change opacity=0.2 to opacity=0, and depending on what is found below, you'll might want to change the colour of the roundd rectangle from {white} to e.g. {red}):

Screenshot 1

After this is done, one can put everything in a mini-page, to have 2 side-by-side figures, using (taken from User Matthew Leingang's answer in OP Two figures side by side):

\begin{figure}
\begin{minipage}{0.5\textwidth}
% here should come all the code for the original image (left side)
\end{minipage}
\begin{minipage}{0.5\textwidth}
% here should come all the code for the "overlay-image" (right side)
\end{minipage}
\end{figure}

Doing so, on the workflow above, yields (I went back from [width=0.5\linewidth] to [width=1\linewidth] here):

\documentclass{article}

\usepackage{graphicx}

\usepackage{tikz}
\usetikzlibrary{calc}

\newcommand*\annotatedFigureBoxCustom[8]{\draw[#5,thick,rounded corners] (#1) rectangle (#2);\node at ($ (#1)!.5!(#2) $)[fill=#6,thick,shape=circle,draw=#7,inner sep=2pt,font=\sffamily,text=#8] {\textbf{#3}};}

\newcommand*\annotatedFigureBox[4]{\annotatedFigureBoxCustom{#1}{#2}{#3}{#4}{white}{none}{none}{black}}
\newcommand*\annotatedFigureText[4]{\node[draw=none, anchor=south west, text=#2, inner sep=0, text width=#3\linewidth,font=\sffamily] at (#1){#4};}
\newenvironment {annotatedFigure}[1]{\centering\begin{tikzpicture}
\node[anchor=south west,inner sep=0,opacity=0.2] (image) at (0,0) { #1};\begin{scope}[x={(image.south east)},y={(image.north west)}]}{\end{scope}\end{tikzpicture}}

\begin{document}

\begin{figure}[h!t]

\begin{minipage}{0.5\textwidth}
\includegraphics[width=1\linewidth]{qUq7A.jpg}
\end{minipage}
\begin{minipage}{0.5\textwidth}
\begin{annotatedFigure}
    {\includegraphics[width=1\linewidth]{qUq7A.jpg}}
    \annotatedFigureBox{0.1113,0.5114}{0.625,0.7951}{the caption you'd like to give to the sub-image}{0.1113,0.5114}
\end{annotatedFigure}
\end{minipage}

\end{figure}

\end{document}

Unfortunately, (due to the lengthy {the caption you'd like to give to the sub-image} which doesn't fit onto the right image) the right-hand-side image gets pushed somewhat down; as can be noticed in the output:

Screenshot 2

Perhaps this could be fixed by limiting the width of the {the caption you'd like to give to the sub-image}, so that it receives automatic line-breaks (and/or reduction of its font-size, e.g. when line-breaks are no longer possible within the rectangle at a certain larger font-size)?

One way to limit the maximum width of the captions, is to introduce e.g. , text width=30mm after e.g. text=#8, but that would limit the width of all the captions. To limit the width for each caption, one can e.g. put a certain caption within a \begin{minipage}{0.75\textwidth}...\end{minipage}.

If you would like to use rotations on the rectangle, you would need to shift the text and the rectangles as well. This could be done using xshift and yshift. One could adapt the code generated from LaTeX Overlay Generator as such, to suit your needs:

\newcommand*\annotatedFigureBox[6]{\draw[orange,thick,rounded corners,rotate=#4, xshift=(#5), yshift=(#6)] (#1) rectangle (#2);\node at ($ (#1)!.5!(#2) $)[text=white] {\small{#3}};}
\newenvironment{annotatedFigure}[1]{\centering\begin{tikzpicture}
\node[anchor=south west,opacity=0.3] (image) at (0,0) { #1};\begin{scope}[x={(image.south east)},y={(image.north west)}]}{\end{scope}\end{tikzpicture}}

Then, one could copy only the rectangle's coordinates as the first 2 arguments of any caption-box (\annotatedFigureBox), into the first 2 arguments of:

\annotatedFigureBox{x1-copy-from-generator,y1-copy-from-generator}{x2-copy-from-generator,y2-copy-from-generator}{the caption you'd like to give to the sub-image}{0}{0}{0}%bl

The last 2 arguments are xshift and yshift respectively, and the one before that (the 4th argument) is the rotation of the rectangle.

Nevertheless, the need for the manual use of xshift and yshift is not so elegant, and furthermore it is hard to guess the size and position of the rectangle in the LaTeX Overlay Generator, if you'll need to rotate it afterwards. Therefor, it might be better to use another generator, from which you could retrieve the coordinates of points, to draw a rectangle or polygon (connect the dots).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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