2

When I compile my document with pdflatex (on Ubuntu) it works fine. I was switching to xelatex for some other issues, but now the following code will no longer compile:

\includegraphics[clip, trim={50px 50px 100px 100px}, width=\textwidth, height=\textwidth]{./images/image1.png}

Here's a MWE that people can play with:

\documentclass{article}
\usepackage{graphicx}
\usepackage{mwe}
\begin{document}
\includegraphics[clip, trim={10px 40px 10px 40px}, width=\textwidth, height=\textwidth]{example-grid-100x100pt.png}
\end{document}

Error:

Illegal unit of measure (pt inserted).

I know px is a non-standard unit in latex, but the included graphics are PNG's, which are inherently and naturally measured in pixels and I need to trim by a specific number pixels. This worked fine with pdflatex and made sense. (If the PNG had a non-standard dpi than I think I could change px by \pdfpxdimen, though I don't understand why it can't just read the metadata and do this itself).

How to I trim an image by a specific number of its pixels in xelatex?

EDIT: Here's my attempt at a workaround with the least possible changes to how I incorporate the image (which will hopefully clarify what I'm trying to do).

  1. Get dpi of image. For example, with image magick: identify -format "%w x %h %x x %y" images/image1.png. Output: 161 x 161 72 x 72 i.e. images is 161x161 pixels, and the dpi is 72 in both dimensions. (Does latex even use the actual dpi of an image? Or does it just assume the default of 72?)
  2. Calculate length of pixel in terms of a unit latex understands: 1 pixels = 1/72 in = .0388 (also, incidentally, 1 pixel = 1bp in this case, so I could just switch px for bp here, but that's not a general solution).
  3. Define a length \mypx with the appropriate value, and switch px for \mypx:
%72 dpi -> 1 px = 1/72 in = .013889
\newlength{\mypx}
\setlength{\mypx}{0.013889in}
\includegraphics[clip, trim={50\mypx 50\mypx 100\mypx 100\mypx}, width=\textwidth, height=\textwidth]{./images/data041_arrIm_image_1.png}

Unfortunately this doesn't work. It seems that lengths can't be used as clip parameters? It's important to me to use pixels as units (in the english sense of the word 'units', not the latex definition). I don't want to manually calculate the equivalent trim value in pt, in etc. every time I mess with it - I need to say 'take off 13 pixels' and trim exactly 13 pixels off the image. I have a lot of images, all with different trimming required and the trimming has to take off a particular integer number of pixels.

I still don't understand why this is so difficult in latex. The fact that it is capable of including a raster image at all means it has to be aware of pixels on some level (or it wouldn't be able to display them), so it should be possible to directly crop by pixels rather than by lengths.

  • 1
    Not an answer, but as a workaround you could use LuaTeX instead of XeTeX (unless you require XeTeX-specific functionality). – Alan Munn Mar 16 at 16:54
  • For fun, does it work without the braces around the trim option? – daleif Mar 16 at 17:18
  • @daleif No, that doesn't change anything. – Alan Munn Mar 16 at 17:19
  • 1
    In pdftex the px unit is not set according to the pixel density of the image you're loading. – egreg Mar 16 at 17:41
  • 1
    px is just a fixed unit not dependent on the image so you can use pt or mm just adjusting by a suitable scale factor, the different units are really just cosmetic differences. – David Carlisle Mar 16 at 19:45
1

If you want to use a length defined using \newlength in the parameter of trim=, like \mypx in your example, you have to be careful about TeX's parsing rules:

In

\includegraphics[clip, trim={10\mypx 40\mypx 10\mypx 40\mypx}, width=\textwidth, height=\textwidth]{example-grid-100x100pt.png}

the spaces after the control sequence \mypx are used as control sequence delimiter, not as regular spaces, so they can not be used to separate the trim arguments. So basically the line above is the same as

\includegraphics[clip, trim={10\mypx40\mypx10\mypx40\mypx}, width=\textwidth, height=\textwidth]{example-grid-100x100pt.png}

which obviously can't work. You can avoid this by adding braces around each dimension. So you can use

\documentclass{article}
\usepackage{graphicx}
\usepackage{mwe}
\newlength{\mypx}
\setlength{\mypx}{0.013889in}
\begin{document}
\includegraphics[clip, trim={{10\mypx} {40\mypx} {10\mypx} {40\mypx}}, width=\textwidth, height=\textwidth]{example-grid-100x100pt.png}
\end{document}

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.