[Tex/LaTex] PNG (with transparent background) and \pdfximage \pdfrefximage

graphicspdftex

I'm using pdflatex (MiKTeX 2.9 portable on Windows 7), and use the pair \pdfximage and \pdfrefximage to include graphics.

Using a PNG with a transparent background yields, in my view, unexpected behavior.

It appears that the index generated by \pdfximage gets corrupted – which makes the "next graphic" unusable. But the graphic after that ones can be used.

I hope my example below illustrates what's happening on my machine:

Is this correct usage, or am I not using the pdflatex primitives correctly?

% SAMPLE
\pdfoutput=1 
\documentclass[german]{article} 
\usepackage[a4paper]{geometry} 
\usepackage{babel} 
% ------------------------------------------ 
% When the following line is used, \LOGOiii yields 'my_other_pic.jpg' - which is not correct.
\pdfximage width 20.0mm height 8.0mm {png_transparent_bg.png} 

% When replacing the above with either of the following lines, \LOGOiii yields 'my_cool_pic.jpg' - which is correct
% (but then I don't have my logo with transparent background)
%\pdfximage width 20.0mm height 8.0mm {my_pic.png}   % png without transparent background
%\pdfximage width 20.0mm height 8.0mm {png_transparent_bg.jpg}  % jpg - no transparent background

\newcommand{\LOGOi}{\pdfrefximage1}

% If png_transparent_bg.png is used, attempting to reference this image results the error:
%     ! pdfTeX error (ext1): cannot find referenced object. (but pdfrefximage3 works!)
\pdfximage height 28.0mm             {my_other_pic.png} 
\newcommand{\LOGOii}{\pdfrefximage2}

\pdfximage height 20.0mm             {my_cool_pic.png} 
\newcommand{\LOGOiii}{\pdfrefximage3}  % 

\begin{document} 
\noindent This pdf illustrates behavior diferences between 'loading' a png graphic     with transparent background as first graphic - via pdfximage.
{\LOGOiii}
{\LOGOii}  % comment to remove compile error
\rule{-15mm}{0mm}
{\LOGOi}
\end{document} 
\endinput 

Console output (attempts to reference 2nd graphic object) – error:

>h:\MikTeXTest\MikTeX.2.9p\texmf\miktex\bin\pdflatex -aux-directory=h:\temp\pdflatex --enable-write18 test_pdfxrefimage.tex 
This is pdfTeX, Version 3.1415926-2.3-1.40.12 (MiKTeX 2.9)
entering extended mode
(Q:\TA ... \TST\test_pdfxrefimage\test_pdfxrefimage.tex
LaTeX2e <2011/06/27>
... console output deleted ...

)) (h:\temp\pdflatex\test_pdfxrefimage.aux)
*geometry* driver: auto-detecting
*geometry* detected driver: pdftex
! pdfTeX error (ext1): cannot find referenced object.
<to be read again> 
               }
l.27 {\LOGOii}
                % uncomment for error
!  ==> Fatal error occurred, no output PDF file produced!
Transcript written on h:/temp/pdflatex/test_pdfxrefimage.log.
>Exit code: 1

Below is console output from pdflatex with above code,
but commented line:

%{\LOGOii}  % comment to remove compile error

compiles ok – but references wrong graphic:

>h:\MikTeXTest\MikTeX.2.9p\texmf\miktex\bin\pdflatex -aux-directory=h:\temp\pdflatex --enable-write18 test_pdfxrefimage.tex 
This is pdfTeX, Version 3.1415926-2.3-1.40.12 (MiKTeX 2.9)
entering extended mode
(Q:\TA ... \TST\test_pdfxrefimage\test_pdfxrefimage.tex
LaTeX2e <2011/06/27>
... console output deleted ...

)) (h:\temp\pdflatex\test_pdfxrefimage.aux)
*geometry* driver: auto-detecting
*geometry* detected driver: pdftex

Overfull \hbox (11.66379pt too wide) in paragraph at lines 24--28
\OT1/cmr/m/n/10 This pdf illustrates behavior diferences between 'loading' a pn
g graphic with transparent background
[1{h:/MikTeXTest/MikTeX.2.9p/localtexmf/fonts/map/pdftex/pdftex.map} <Q:/TA.../TST/test_pdfxrefimage/my_other_pic.png (PNG copy)> <Q:/TA.../TST/test_pdfxrefimage/png_transparent_bg.png>]
(h:\temp\pdflatex\test_pdfxrefimage.aux) )
(see the transcript file for additional information)<h:/MikTeXTest/MikTeX.2.9p/
texmf/fonts/type1/public/amsfonts/cm/cmr10.pfb>
Output written on test_pdfxrefimage.pdf (1 page, 33610 bytes).
Transcript written on h:/temp/pdflatex/test_pdfxrefimage.log.
>Exit code: 0

References "my_other_pic.png" but should actually use "my_cool_pic.png".

Best Answer

The obvious problem is that the generated number is not 2 for the second image, as a simple

\showthe\pdflastximage

put just after

\pdfximage height 28.0mm             {my_other_pic.png} 

will show:

> 3.
l.18 \showthe\pdflastximage

This is probably due to the fact that one more picture object is included for "masking" the one with transparent background.

There is another primitive, \pdflastximage that can (and should) be used for these situations: it is a read-only integer that is loaded with the number assigned to the last object included with \pdfximage. However you can't say

\newcommand{\LOGOi}{\pdfrefximage\pdflastximage}

because this would always refer to the last image. Some lower level trickery is needed:

\pdfximage width 20.0mm height 8.0mm {png_transparent_bg.png} 
\edef\LOGOi{\pdfrefximage\the\pdflastximage\relax}

\pdfximage height 28.0mm             {my_other_pic.png} 
\edef\LOGOii{\pdfrefximage\the\pdflastximage\relax}

\pdfximage height 20.0mm             {my_cool_pic.png} 
\edef\LOGOiii{\pdfrefximage\the\pdflastximage\relax}

Each \edef will expand \the\pdflastximage to the current value; in your case, the expansions of \LOGOi, \LOGOii and \LOGOiii will be

> \LOGOi=macro:
->\pdfrefximage 1\relax .

> \LOGOii=macro:
->\pdfrefximage 3\relax .

> \LOGOiii=macro:
->\pdfrefximage 4\relax .

as required for a correct later usage of the images.

It's quite unclear why you don't want to use the higher level \includegraphics for this. If you're afraid that multiply used pictures are included multiple times in the PDF file, don't be.


In case you've inherited some document where these low level tricks are used, just comment out the lines and change them according to this model

%\pdfximage width 20.0mm height 8.0mm {png_transparent_bg.png} 
%\edef\LOGOi{\pdfrefximage\the\pdflastximage\relax}
%\pdfximage height 28.0mm             {my_other_pic.png} 
%\edef\LOGOii{\pdfrefximage\the\pdflastximage\relax}
%\pdfximage height 20.0mm             {my_cool_pic.png} 
%\edef\LOGOiii{\pdfrefximage\the\pdflastximage\relax}

\usepackage{graphicx}
\newcommand\LOGOi{\includegraphics[width 20.0mm, height 8.0mm]{png_transparent_bg.png}}
\newcommand{\LOGOii}{\includegraphics[height 28.0mm]{my_other_pic.png}}
\newcommand{\LOGOiii}{\includegraphics[height 20.0mm]{my_cool_pic.png}}