Créer un effet de zoom (statique)

Dans ce billet, je vais vous donner deux façons de faire des effets de zoom sur une zone d’une figure pour des documents statiques.

En utilisant les références croisées

Mettons que vous ayez une image dans une (sous-)figure, et que vous vouliez dessiner un cadre dessus pour faire référence à une autre (sous-)figure, comme illustré ci-après :

Zoom sur une figure (en utilisant les légendes)
Zoom sur une figure (en utilisant les légendes)

 

Dans mon cas, j’ai utilisé les légendes des sous-figures (générées avec le package subcaption). Dans le préambule :

\newcommand{\zoom}[4]{
	\begin{tikzpicture}
	  	\draw (0,0) node[anchor=south west,inner sep=0] (image) { 
	  		#1
	  	 };
	  \begin{scope}[x={(image.south east)},y={(image.north west)}]
			%\draw [step=0.05,gray,very thin] (0,0) grid (1,1);
			\draw [red, very thick] (#2) rectangle +(#3);
				\node [fill=red, font=\footnotesize, inner sep=0em] at (#2) [above,anchor=south west] {\subref{#4}};
	  \end{scope}				
	\end{tikzpicture}	
}

Dans le corps du document :

\begin{figure}
	\begin{subfigure}[t]{\linewidth}
		\zoom{
			\includegraphics[<dimensions>]{<Fichier de l'image 1>}
		}{0.45,0.475}{0.120,0.120}{sub:image1}
		\caption{}
	\end{subfigure}\\
	\begin{subfigure}[t]{\linewidth}
		\includegraphics[<dimensions>]{<Fichier de l'image 2>}
		\caption{}
		\label{sub:image2}
	\end{subfigure}
\end{figure}

Ici, on profite des références croisées pour s’assurer de bien faire référence à la bonne figure. Il faut donc compiler deux fois. J’ai ainsi défini la commande \zoom, qui prend pour arguments :

  1. La figure à mettre en fond
  2. les coordonnées (relatives, entre 0 et 1) du coin inférieur gauche du cadre rouge
  3. les dimensions (relatives toujours) du cadre
  4. le label de la figure à laquelle il faut faire référence.

Bien entendu, il est possible de répéter cette opération autant de fois que souhaité (en remplaçant le \includegraphics par \zoom). Pour vous aider à faire la positionnement du cadre, vous pouvez décommenter la ligne suivante :

%\draw [step=0.05,gray,very thin] (0,0) grid (1,1);

pour afficher une grille régulière avec un espacement de 0,05.

Effet d’agrandissement de la fenêtre

Peut-être voudrez-vous faire votre zoom de façon monolithique, c’est-à-dire au sein d’une même figure. Si vous souhaitez un rendu plus visuel, mais peut-être un peu moins rigoureux, comme illustré sur la figure suivante :

Effet de zoom (avec agrandissement)
Effet de zoom (avec agrandissement)

Alors, commencez par mettre dans votre préambule :

\usepackage{tikz}
\newcounter{imageZoom}
\newcounter{imageZoomp}
 
\usetikzlibrary{positioning}
\usetikzlibrary{calc}
 
\newcommand{\zoomZero}[2][]{
	\setcounter{imageZoom}{1}
	\draw (0,0) node[anchor=south west,inner sep=0] (image\theimageZoom) { 
  			#2
  	 	};
}
 
\newcommand{\zoomIn}[4][below]{
 	\refstepcounter{imageZoom}
 	\setcounter{imageZoomp}{\value{imageZoom}}
 	\addtocounter{imageZoomp}{-1}
	\begin{scope}[shift=(image\theimageZoomp.south west),x={(image\theimageZoomp.south east)},y={(image\theimageZoomp.north west)}]
		%\draw [step=0.05,gray,very thin] (0,0) grid (1,1);
		\node[inner sep=0,anchor=center] (rectanglebg\theimageZoomp) at (#3){};
		\node[inner sep=0,anchor=center] (rectanglehd\theimageZoomp) at ($(rectanglebg\theimageZoomp)+(#4)$){};
		\node[inner sep=0,anchor=center] (rectanglebd\theimageZoomp) at (rectanglehd\theimageZoomp |- rectanglebg\theimageZoomp){};
		\node[inner sep=0,anchor=center] (rectanglehg\theimageZoomp) at (rectanglehd\theimageZoomp -| rectanglebg\theimageZoomp){};
		\draw (#3) rectangle +(#4);
 	\end{scope}
 	\draw (0,0) node[anchor=north west,inner sep=0,#1=of image\theimageZoomp] (image\theimageZoom) {
		\phantom{#2}
	};
	\draw  (rectanglebg\theimageZoomp.center) -- (image\theimageZoom.south west);		
	\draw  (rectanglebd\theimageZoomp.center) -- (image\theimageZoom.south east);		
	\draw  (rectanglehd\theimageZoomp.center) -- (image\theimageZoom.north east);		
	\draw  (rectanglehg\theimageZoomp.center) -- (image\theimageZoom.north west);
	\draw (0,0) node[anchor=north west,inner sep=0,#1=of image\theimageZoomp]  {
		#2
	};
	\draw (image\theimageZoom.south west) rectangle (image\theimageZoom.north east);
}

Puis, dans le corps de document :

\begin{tikzpicture}
	\zoomZero{\includegraphics{<Première image>}}
	\zoomIn{\includegraphics{<Deuxième image>}}{0.45,0.475}{0.120,0.120}
	\zoomIn{\includegraphics{<Troisième image>}}{0.45,0.475}{0.120,0.120}
\end{tikzpicture}

On utilise ici deux commandes distinctes : \zoomZero et \zoomIn, afin de différencier l’image initiale des images zoomées. Les options de \zoomIn sont sensiblement les mêmes que précédemment :

  1. Image à inclure
  2. Position du coin inférieur gauche de la fenêtre sur la figure précédente
  3. Dimensions de cette fenêtre

Cette fois encore, vous pouvez afficher la grille régulière en décommentant la ligne correspondante, dans la définition de la commande \zoomIn.

Le plus : en option des commandes \zoomIn, il est possible de spécifier la position de la figure par rapport à la figure précédente (en dessous par défaut). Il est aussi possible de définir le style des traits pour les zoom et l’espacement par défaut, en option du tikzpicture. Exemple :

\begin{tikzpicture}[node distance = 1em,dashed,red,thick]
	\zoomZero{\includegraphics[width=0.45\textwidth]{Geant5}}
	\zoomIn[right]{\includegraphics[width=0.45\textwidth]{Geant4}}{0.45,0.475}{0.120,0.120}
	\zoomIn{\includegraphics[width=0.45\textwidth]{Geant3}}{0.45,0.475}{0.120,0.120}
	\zoomIn[left]{\includegraphics[width=0.45\textwidth]{Geant2}}{0.45,0.475}{0.120,0.120}
	\zoomIn{\includegraphics[width=0.45\textwidth]{Geant1}}{0.45,0.475}{0.120,0.120}
	\zoomIn[right]{\includegraphics[width=0.45\textwidth]{Geant0}}{0.45,0.475}{0.120,0.120}
\end{tikzpicture}
Personnalisation du style d'agrandissement
Personnalisation du style d’agrandissement

Pour aller plus loin

Il est bien sûr possible de combiner les commandes précédentes avec les barres d’échelle.