62

I'm including a number of PDF images in my document using \includegraphics. I'm wondering if there's a way for LaTeX to adjust their color profile, hopefully the same way it can flip images upside down, resize, and crop, as here: http://en.wikibooks.org/wiki/LaTeX/Importing_Graphics#Including_graphics

Let me detail a little more my desired outcome, in case there's another way to achieve this: The images are brightly colored---I'd like to reduce color levels, or possibly render them grayscale, and I'd prefer to not have to do external pre-processing, if this is possible.

I'm using XeTeX.

5
  • 2
    See also tex.stackexchange.com/questions/3322/…
    – Caramdir
    Sep 22, 2011 at 21:59
  • 7
    No, \includegraphics can't change the image color. You need to use an external graphic editor. Sep 22, 2011 at 22:05
  • 3
    If all you want to do is reduce the brightness then you could overlay a translucent rectangle on the image. It wouldn't be anywhere near as good as doing it in an external program, though. Sep 23, 2011 at 6:55
  • 2
    @MartinScharrer I think your comment is an answer :-)
    – Joseph Wright
    Sep 23, 2011 at 7:04
  • 1
    It's healthy to note that neither the image filetype (.pdf, .jpg, .png, etc) nor the engine per se have influence on \includegraphics, so the macro will behave the same for all cases. Aug 17, 2012 at 10:20

4 Answers 4

40

No, \includegraphics can't change the image color. You need to use an external image editor. The graphics/graphicx packages are more or less just interfaces which pass the image to the output driver, like dvips or pdftex. Therefore you are limited to the features provided by these drivers. Image manipulation is not part of these drivers and even if it would be very difficult to have an identical interface for these in graphics/graphicx.

For anything except resizing, trimming/clipping and rotating you need to use an external image editor. However, using PGF/TikZ you can place some overlays before and behind the image. If the image has transparent parts you could add a background color etc.

52

(Importantly, this does not work with XeTeX. I mostly tested using pdfTeX, but things also seem to work in LuaTeX.)

In a pdf file, colors of an included image can be affected by a /Decode array. This is accessed via the decodearray keyword of \includegraphics.

However: this fails in some cases when the color model is cmyk; and this does not allow to change the color space from whatever color space the image has. My impression is that changing the color space from within pdfTeX (i.e. turn grayscale to rgb, or rgb to cmyk, etc.) is impossible.

Grayscale is the easiest. Say we want to reduce contrast and make the image overall darker. We'll map black (0) to some dark gray (0.2) and white (1) to some lighter gray (0.5). This is done using decodearray={0.2 0.5} (braces can be omitted).

\documentclass{article}
\usepackage{graphicx}
\begin{document}
\includegraphics{example-image.jpg}

\includegraphics[decodearray={0.2 0.5}]{example-image.jpg}
\end{document}

For an rgb example we can use hacker.jpg from the ConTeXt examples. For a cmyk example, create a copy of example-image.jpg with this color space; I used the convert command-line tool from imagemagick:

convert `kpsewhich example-image.jpg` -colorspace cmyk /tmp/example-image-cmyk.jpg

letting kpsewhich do the job of finding where example-image.jpg is. Then, try

\documentclass{article}
\usepackage{graphicx}
\begin{document}
\includegraphics{hacker.jpg}

\includegraphics[decodearray={0.2 0.3 1 0 1 0.8}]{hacker.jpg}

\includegraphics{example-image-cmyk.jpg}

\includegraphics[decodearray={0.2 0.2 1 0 1 0.8 1 0}]{example-image-cmyk.jpg}
\end{document}

Note that for the rgb color profile the /Decode array contains 6 numbers, and for cmyk, 8 numbers. Each pair of numbers describes the linear transformation to operate on the corresponding channel. The first array thus imposes the amount of red, inverts the amount of green light, and puts lots of blue.

The second array should fix the amount of cyan, inverts magenta, puts lots of yellow, and inverts the amount of black ink. It doesn't. Why? Looking at the pdf file, I note that there are two /Decode entries in the same dictionary, one of the form /Decode[0.2 0.2 1 0 1 0.8 1 0] and one of the form /Decode [1 0 1 0 1 0 1 0]. The second entry takes precedence, at least on viewers I tried (perhaps this is mandated by the standard), and it inverts all channels (see below for why). If we edit the pdf file to replace the second /Decode [...] by any other key of the same length (being lazy, I do /Decode/xxxxxx), our /Decode array takes effect, and the result is as wanted.

Why is the second /Decode array there? Well, there appear to exist two types of cmyk, with slightly different conventions on whether white should be all zeros or all ones, and pdfTeX is clever enough to detect things and insert the appropriate /Decode array: without it, (some?) jpg images in the cmyk color space would be displayed and printed with inverted colors.

Anyhow, I'm going to ask a question about how to avoid this second /Decode array, since editing the pdf file is not pretty.

NB: In general, it is better practice not to include the file extension in the argument of \includegraphics, but since there is a need here to know color spaces precisely, so I don't want to worry about getting a png instead of jpg, or whatever.

9
  • 1
    Do you know if it is possible to create a single-color vector image without an actual color, so that TeX sets the color? E.g. for symbols that are included as graphic but should change their color depending on the surrounding text …
    – Tobi
    Dec 16, 2013 at 17:57
  • 1
    @Tobi I don't know. I would expect it to be possible for vector graphics (e.g., eps with no mention of colour might do the trick), but not for raster formats. I may be wrong. Have you seen Heiko's answer tex.stackexchange.com/a/65083/2707 ? It seems to point in that direction. Dec 16, 2013 at 17:59
  • 2
    Huh, bravo! That's very interesting. Dec 16, 2013 at 18:14
  • 1
    Thanks, I didn't saw the other answer. Looks like it answers my question – unfortunately it works only with pdflatex
    – Tobi
    Dec 16, 2013 at 19:02
  • 1
    @Karlo: I suspect that decodearray only works with jpg and not pdf inclusion but I don't have time to investigate. Please ask a new question linking to this one (and specifically to my answer I suppose), so that other people may see your question and help you. Apr 2, 2018 at 3:00
6

Interestingly, for the vector graphics that I've tried it on, \color command actually changes all the black into whatever color was given.

7
  • 4
    This is supported by pdfTeX/LuaTeX only and only if the graphics does not contain color settings. This behavior can be overwritten by the option resetcolor for \includegrahics. Then pdftex.def calls \normalcolor before the image is included. May 30, 2014 at 1:34
  • 2
    Interesting. Then I suppose there is no way to change the other colors. For instance, leave the black alone, but change the grey to red?
    – Mark
    May 30, 2014 at 1:56
  • 1
    No. The PDF image is included as whole unit. May 30, 2014 at 2:00
  • Could you please give an example code?
    – tvk
    Nov 5, 2016 at 15:33
  • 2
    \color{blue} \includegraphics{line-art}
    – Mark
    Nov 7, 2016 at 1:15
3

I ran into this issues for jpg and was able to use the decodearray to achieve my desired results. Unsure how it works with pdf. It seems by setting all arguments, besides the first one to .5 the color is washed out. The first argument allows you to change the darkness. 1 gives you inverted and 0 is extremely dark.

\includegraphics[decodearray={.1 .5 .5 .5 .5 .5}]{img.jpg}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .