# How do I get the exact dimension of a picture in LaTeX?

This question is pretty simple: I'd like to have the possibility to get the exact size of a picture in LaTeX with, for example, the macro \the.

In fact, I've founded the way \settoheight{} and so on, but it didn't work at all. What I've got doesn't match with what I can see in the image properties (I suppose that's the name in English). The result: 8pt versus 1300 pixels. It's may be a mis-use...

Edit: In the end, my aim was to find a way to fit the picture in LaTeX. If width and height were both less than the dimensions of the body, then it should just be centred. It look like this :

Require:

\usepackage{graphicx}
\usepackage{xifthen}
\usepackage{calc}


Code (pretty ugly, I agree):

% Centrering+fitting for image, with captation and label (not auto)
\newlength\imageheight
\newlength\imagewidth
\newcommand{\pic}[3]{%
\settoheight\imageheight{\includegraphics{pictures/#1.png}}%
\settowidth\imagewidth{\includegraphics{pictures/#1.png}}%
\ifthenelse{\lengthtest{\imagewidth > \textwidth}}{\ifthenelse{\lengthtest{\imageheight > \imagewidth}}{\par\vspace{0.95em}%
\begin{figure}
\centering\includegraphics[height=0.85\textheight]{pictures/#1.png}
\caption{#2}
\label{#3}
\end{figure}%
\par\vspace{0.95em}}{\par\vspace{0.95em}%
\begin{figure}
\centering\includegraphics[width=0.95\textwidth]{pictures/#1.png}
\caption{#2}
\label{#3}
\end{figure}%
\par\vspace{0.95em}}}{\ifthenelse{\lengthtest{\imageheight > \textheight}}{\par\vspace{0.95em}%
\begin{figure}
\centering\includegraphics[height=0.85\textheight]{pictures/#1.png}
\caption{#2}
\label{#3}
\end{figure}%
\par\vspace{0.95em}}{\par\vspace{0.95em}%
\begin{figure}
\centering\includegraphics{pictures/#1.png}
\caption{#2}
\label{#3}
\end{figure}%
\par\vspace{0.95em}}}}
%


To use it : put your png files in a "pictures" directory, then, just simply call the picture like this : \pic{name_whitout_extension}{Captation_if_needed}{Label_if_needed}.

Edit 2 :

Thanks to Martin Scharrer's easyfig package, I've got a more or less 1,6 times faster solution to put my pictures, centred, with the perfect size.

Version v1.2 – 2012/05/15

This could be useful for some others, I hope.

-
8pt seems really small, but still, you can't directly compare pt and pixels. 1pt is a physical length (1/72.27 inches), pixels are logical units. The conversion between pixels and points depends on the resolution of the image (which is usually measured in "pixels per inch", or "dpi"). –  Jake Apr 26 '12 at 21:10
Then, I guess it's depend of my paper dimension, since I work with PDF. Thanks for it. Still, it's not really the needed answer. –  Julien Apr 26 '12 at 21:14
If an image has a natural resolution of 300dpi and it says about itself that its width is 1200 pixels, then the natural width (as seen by LaTeX) is 4 inches. At 600dpi the width would be 2 inches. –  egreg Apr 26 '12 at 21:16
@Julien: You seem to want to rescale the image dependent on how wide it is. Note that this can be easily done using my adjustbox package. It can add min width and max width options to \includegraphics to only scale an image if it is wider or narrower than a certain width. –  Martin Scharrer Apr 26 '12 at 22:30
Note that adjustbox now includes keys to set captions and label as well as turning the content into a float. Also, check out my other package easyfig, which also might be useful for you. –  Martin Scharrer Aug 17 '12 at 18:25

If all you want is to limit the width of your image to some maximum value (like \linewidth), you could simply use the approach described in the TeX FAQ:

\documentclass[a5paper]{article}
\usepackage{graphicx}

\makeatletter
\def\maxwidth{%
\ifdim\Gin@nat@width>\linewidth
\linewidth
\else
\Gin@nat@width
\fi
}
\makeatother

\begin{document}
\centering\includegraphics[width=\maxwidth]{largebottle}

\includegraphics[width=\maxwidth]{largesidebottle}
\end{document}


To actually measure and output the dimensions, \settoheight and \settowidth should work. You can convert the pt units to other units using the printlen package, as Werner pointed out in the comments.

ImageMagick (identify -verbose bottle.jpg) shows the geometry to be 1408x714 pixels, with a resolution of 300x300 pixels per inch, which translates to 1408 px/300 px per in*72.27 pt per in=339.1872 pt and 714 px/300 px per in * 72.27 pt per in = 172.0026 pt.

\documentclass[11pt ]{article}
\usepackage{graphicx}
\usepackage{printlen}
\uselengthunit{cm}

\newlength\imageheight
\newlength\imagewidth

\begin{document}

\settoheight\imageheight{\includegraphics{bottle}}
\settowidth\imagewidth{\includegraphics{bottle}}
\includegraphics{bottle}

Height: \the\imageheight\ (\printlength{\imageheight})

Width: \the\imagewidth\ (\printlength{\imagewidth})

\end{document}

-
Perhaps suggest the use of printlen in order to print a length in a different unit. Even better, extend it to print a length in px! Also, you don't need the calc package. –  Werner Apr 26 '12 at 21:31
Thanks ! It's work pretty fine, thus, the value it give to is ... more or less the pixels value. But I don't need to be perfectly accurate. Thanks a lot ! –  Julien Apr 26 '12 at 21:32
@Werner: Good idea, and thanks for the note about the calc package! However, to convert to px, one would need to know the image resolution, and I don't know how to read that from the image file within LaTeX. –  Jake Apr 26 '12 at 21:42
@Jake: \usepackage[export]{adjustbox} provides an max width key for \includegraphics. –  Martin Scharrer Apr 26 '12 at 22:37
What does \Gin@nat@width mean? –  azetina Aug 17 '12 at 16:20

LaTeX doesn't use pixels. Pixels aren't a print format. pdflatex allows a px unit but this is simply converted to points (pt) like everything else in TeX. The pixel-to-point ratio depends on the image density which is in dots-per-inch (DPI). By default 72 DPI are used. A TeX point is 1/72.27 inches and a PostScript/PDF point (bp in TeX) is 1/72 inches. If your image has a large DPI value but pdflatex can't read that from the images meta-data this conversion might be wrong (because 72 DPI are assumed) and your image is sized incorrectly. Sometimes simply converting your image or opening and saving it fixes the meta-data.

About how to measure all dimensions of the image:

Don't include the image multiple times to measure its different sizes. Store it manually in a box (e.g. \mybox) and then you can access the box dimensions directly using \ht\mybox (height), \wd\mybox (width) and \dp\mybox (depth). All the \setto... macros you have mentioned do exactly the same with a temp box.

\newsavebox\mybox

\newcommand{\pic}[1]{%
\sbox\mybox{\includegraphics{#1}}%
Height: \the\ht\mybox
Width: \the\wd\mybox
Depth: \the\dp\mybox % For images usually 0 except if rotated
\ifdim\wd\mybox>.6\textwidth
% width is larger than 60% of the text width ...
\fi
% Insert the image:
\usebox\mybox
}


You can also need the \@tempboxa box register (requires \makeatletter .. \makeatother) or directly the box register number 0: \sbox0{...} \ht0 ...

-
Wouaw. Didn't knew so much. Well, since I'm not an informatician, can't tast the exact details, but is this way a more simple one, or a more optimized one (I mean, this will go faster with more accuracy) ? –  Julien Apr 27 '12 at 13:15
It's both more simple (i.e. lower level) and (therefore) faster. The \settosomething macros are higher-level wrappers around code like this. –  Martin Scharrer Apr 27 '12 at 14:50

Although the question asks how to do this in LaTeX, I am also adding an answer to show how to do this using a high level interface in ConTeXt.

Whenever you use \externalfigure, ConTeXt makes the dimensions (and number of pages for pdf images) available using the macros \figurenaturalwidth, \figurenaturalheight, and \noffigurepages. If you don't want the image to be included in the document but just want to measure its dimensions, use \getfiguredimensions. The following example gets the dimensions for a remote hosted image:

\starttext
\getfiguredimensions[http://placekitten.com/500/300][method=png]
\startTABLE
\NC Width  \NC \the\dimexpr\figurenaturalwidth  \NC \NR
\NC Height \NC \the\dimexpr\figurenaturalheight \NC \NR
\NC Pages  \NC \noffigurepages                  \NC \NR
\stopTABLE
\stoptext


\figurenaturalwidth and ...height return the units in sp. I use\the\dimexpr to convert the result to points. One could also use the Lua function number.todimen(...) for a more versative conversion routine.

NOTE As in LaTeX, the dimension calculations use the default DPI specified in pdftex/luatex. So, Jake's comment of comparing px and pt is still relevant.

Based on the edited question, in ConTeXt you can use:

\externalfigure[figurename][maxwidth=\textwidth, maxheight=\textheight]


This will shrink the image so that its height and width do not exceed maxheight and maxwidth. If you need to set these options for many figures, you can use:

\defineexternalfigure[MaxWidthAndHeight][maxwidth=\textwidth, maxheight=\textheight]
\externalfigure[figurename][MaxWidthAndHeight][frame=on]


(where I used frame=on only to show how to add other options, if needed).

-