# clip a image with relative coordinate

I want to clip a image with relative coordinate.

see below example:

\documentclass{standalone}
\usepackage{tikz}
\tikzset{mynode/.style={draw,solid,circle,inner sep=1pt}}

\usepackage{etoolbox}
\newbool{DEBUG}
\booltrue{DEBUG}
%\boolfalse{DEBUG}

\begin{document}
\def\infilename{tiger.pdf}
\begin{tikzpicture}[>=latex]
\node[anchor=south west,inner sep=0] (image) at (0,0,0) {\includegraphics[width=5cm]{\infilename}};
\begin{scope}[x={(image.south east)},y={(image.north west)}]
\clip (0.4,0.6) rectangle (0.5,0.7);
\ifbool{DEBUG}{\small
\draw[help lines,xstep=.1,ystep=.1] (0,0) grid (1.001,1.001);
\foreach \x in {1,...,9} { \node [anchor=north] at (\x/10,0) {\x};}
\foreach \y in {1,...,9} { \node [anchor=east] at (0,\y/10) {\y};}
};
\end{scope}
\end{tikzpicture}

\end{document}


But it seems only clip the help lines but not on origin picture. I like relative coordinate because it's more easy to locate the exact position which I want.

Is it possible to fix it? In this example, I only want to extract the rectangle area (0.4,0.6) to (0.5,0.7). say full image is (0,0) to (1,1).

The problem is that you need to need to know how large the image is before you can apply a relative clip. The usual ways to do that are to use a savebox or use \phantom.

Using savebox:

\tikzset{mynode/.style={draw,solid,circle,inner sep=1pt}}
\usetikzlibrary{calc}

\usepackage{etoolbox}
\newbool{DEBUG}
\booltrue{DEBUG}
%\boolfalse{DEBUG}

\newsavebox{\tempbox}

\usepackage{mwe}% for example images

\begin{document}
\def\infilename{example-image}%
\savebox{\tempbox}{\includegraphics[width=5cm]{\infilename}}%
\fbox{
\begin{tikzpicture}[>=latex]
\path (0,0) (\wd\tempbox,\ht\tempbox);% set bounding box
\begin{scope}[x={\wd\tempbox},y={\ht\tempbox}]
\clip (0.4,0.6) rectangle (0.5,0.7);
\node[anchor=south west,inner sep=0] {\usebox\tempbox};
\ifbool{DEBUG}{\small
\draw[help lines,xstep=.1,ystep=.1] (0,0) grid (1.001,1.001);
\foreach \x in {1,...,9} { \node [anchor=north] at (\x/10,0) {\x};}
\foreach \y in {1,...,9} { \node [anchor=east] at (0,\y/10) {\y};}
};
\end{scope}
\end{tikzpicture}}

\end{document}


Using \phantom:

\documentclass{standalone}
\usepackage{tikz}
\tikzset{mynode/.style={draw,solid,circle,inner sep=1pt}}
\usetikzlibrary{calc}

\usepackage{etoolbox}
\newbool{DEBUG}
\booltrue{DEBUG}
%\boolfalse{DEBUG}

\usepackage{mwe}% for example images

\begin{document}
\def\infilename{example-image}
\fbox{
\begin{tikzpicture}[>=latex]
\node[anchor=south west,inner sep=0] (image) {\phantom{\includegraphics[width=5cm]{\infilename}}};
\begin{scope}[x={(image.south east)},y={(image.north west)}]
\clip (0.4,0.6) rectangle (0.5,0.7);
\node[anchor=south west,inner sep=0] {\includegraphics[width=5cm]{\infilename}};
\ifbool{DEBUG}{\small
\draw[help lines,xstep=.1,ystep=.1] (0,0) grid (1.001,1.001);
\foreach \x in {1,...,9} { \node [anchor=north] at (\x/10,0) {\x};}
\foreach \y in {1,...,9} { \node [anchor=east] at (0,\y/10) {\y};}
};
\end{scope}
\end{tikzpicture}}

\end{document}


• Great answer, and I wish to define "\includegraphics[width=5cm]{\infilename}" as a macro to avoid a duplicate code section. how can we do it? – Beatlej Apr 6 '15 at 18:22
• Frankly, a savebox is faster than a macro. – John Kormylo Apr 6 '15 at 19:26

I think it's better to combine savebox and phantom.

See result below:

\documentclass{standalone}
\usepackage{tikz}
\usepackage{etoolbox}

\tikzset{mynode/.style={draw,solid,circle,inner sep=1pt}}

\usepackage{etoolbox}
\newbool{DEBUG}
\booltrue{DEBUG}
%\boolfalse{DEBUG}

\begin{document}
\def\infilename{tiger.pdf}
\newsavebox{\graphbox}
\savebox{\graphbox}{\includegraphics[width=5cm]{\infilename}}
\begin{tikzpicture}[>=latex]
\node[anchor=south west,inner sep=0] (image) at (0,0,0) {\phantom{\usebox\graphbox}};
\begin{scope}[x={(image.south east)},y={(image.north west)}]
\ifbool{DEBUG}{\small
\draw[help lines,xstep=.1,ystep=.1] (0,0) grid (1.001,1.001);
\foreach \x in {1,...,9} { \node [anchor=north] at (\x/10,0) {\x};}
\foreach \y in {1,...,9} { \node [anchor=east] at (0,\y/10) {\y};}
};
\clip (0.4,0.6) rectangle (0.5,0.7);
\node[anchor=south west,inner sep=0] {\usebox\graphbox};
\end{scope}
\end{tikzpicture}

\end{document}


result picture (with helplines on):

Without tikz:

\documentclass{article}
\usepackage{graphicx,calc}
\def\mygraphic{\includegraphics{tiger}}
\newlength\gh \setlength\gh{\heightof{\mygraphic}}
\newlength\gw \setlength\gw{\widthof{\mygraphic}}
\begin{document}
\includegraphics[scale=0.5,trim= {.4\gw} {.6\gh} {.5\gw} {.3\gh}, clip]{tiger}%
\end{document}


1. If open the debug option, it will print the help lines.
2. If comment out the debug option, it will only output the clip area.

code as below:

\documentclass{standalone}
\usepackage{tikz}
\usepackage{graphicx}
\usepackage{calc}

\usepackage{etoolbox}
\newbool{DEBUG}
\booltrue{DEBUG}
%\boolfalse{DEBUG}

\begin{document}

\newsavebox{\graph}\savebox{\graph}{\includegraphics[]{\infilename}}
\newlength\gh\setlength\gh{\heightof{\usebox\graph}}
\newlength\gw\setlength\gw{\widthof{\usebox\graph}}

\begin{tikzpicture}[>=latex,
image/.style={anchor=south west,inner sep=0}]
\ifbool{DEBUG}{
\node[image] (NI) at (0,0){\phantom{\usebox\graph}};
\begin{scope}[x={(NI.south east)},y={(NI.north west)}]
\draw[help lines,xstep=.1,ystep=.1] (0,0) grid (1.001,1.001);
\foreach \x in {1,...,9} { \node [anchor=north] at (\x/10,0) {\x};}
\foreach \y in {1,...,9} { \node [anchor=east] at (0,\y/10) {\y};}
\end{scope}
};
\clip (0.4\gw,0.6\gh) rectangle (0.5\gw,0.7\gh);
\node[image] {\usebox\graph};
%\draw[|<->|,very thick,red!60]
%    (0.5\gw,0.5\gh) -- node[pos=0.5, auto] {$600$} ++(0.2\gw,0\gh);
\end{tikzpicture}

\end{document}


Output when debug option on:

Output when debug option off: