[Tex/LaTex] Montage multiple PDF images, scaled to each other’s dimensions, on a single PDF page

graphicspdfscaling

I though "montage" would be the most appropriate term here, since in Latex we mostly deal with multi-page documents (and I was afraid that terms like "concatenate", "append", "collect" etc. could be misunderstood in that context). I'd like to do something similar to the nup option of pdfpages, just with individual rotation and scaling. Anyways, let me show you what I want, through an example with plain images, using ImageMagick's convert and montage commands.


Let's say I have one input image file, testred.png, 350×250 pixels in size, generated like this:

convert -size 350x250 xc:red -pointsize 40 -draw "text 0,40 'testRED'" testred.png

Then, I have a second image file: testgreen.png, 300×200 pixels in size:

convert -size 300x200 xc:green -pointsize 40 -draw "text 0,40 'testGREEN'" testgreen.png

What I want to do is: rotate the second image; scale/resize so the second image's rotated width (originally the height) matches the first image's width; place the second image below the first one without any padding; and output a document of that montage without any margins. Using ImageMagick's montage, this can be achieved with (note, there must be a space between opening parenthesis \( and the filename testgreen.png!):

montage       testred.png       \( testgreen.png           -rotate 90           -resize $(identify -ping -format "%w" testred.png)x       \)     -geometry +0+0 -tile 1x     testmontage.png

# ... or as single line:

montage testred.png \( testgreen.png -rotate 90 -resize $(identify -ping -format "%w" testred.png)x \) -geometry +0+0 -tile 1x testmontage.png

The output file, testmontage.png, has a size of 350×775 pixels:

$ file testmontage.png
testmontage.png: PNG image data, 350 x 775, 16-bit/color RGB, non-interlaced

… and looks like this:

testmontage.png

… which is what I wanted.

Note that one of the important things for me here, is that nowhere I had to explicitly calculate numerically the new size of the second file (although, I needed to call identify in a subshell, to get that information).


Now, I'd like to do the same – but with PDF files. ImageMagick's convert can again be used to generate the same input files, but as PDFs:

convert -size 350x250 xc:red -pointsize 40 -draw "text 0,40 'testRED'" testred.pdf
convert -size 300x200 xc:green -pointsize 40 -draw "text 0,40 'testGREEN'" testgreen.pdf

The sizes, while specified in pixel units, are interpreted as point units in the PDF:

$ pdfinfo testred.pdf | grep 'Page size'
Page size:      350 x 250 pts
$ pdfinfo testgreen.pdf | grep 'Page size'
Page size:      300 x 200 pts

I know that if I use the standalone class for a single PDF image, even without any explicit size specifications:

% file: montager.tex

\documentclass{standalone}
\usepackage{graphicx}

\begin{document}
  \includegraphics{testred.pdf}
\end{document}

… the output PDF file will be resized, so it matches (almost exactly) the input PDF size:

$ pdflatex montager.tex
...
Output written on montager.pdf (1 page, 262127 bytes).
Transcript written on montager.log.
$ pdfinfo montager.pdf | grep 'Page size'
Page size:      349.999 x 249.999 pts

… which is good.

However, I'm not sure how to proceed from here, as in the easiest possible way in respect to positioning, and obtaining the length to scale to. Note that \paperwidth, \linewidth and the like do not change within the \begin/\end section (and I cannot tell where else I could obtain width information); and \par, \\ and the like to open a new line (so I position below) are either ignored or crash pdflatex.

I'm pretty sure tikz could be used for this – but it's been a while, and I've forgotten most of it … so I thought, let me ask a question instead :)

Best Answer

Well, I think I solved it - tikz was indeed the way to go:

% file: montager.tex

\documentclass{standalone}
\usepackage{graphicx}
\usepackage{tikz}
\usetikzlibrary{positioning,calc}

\begin{document}
  \begin{tikzpicture}
    \node[inner sep=0] (testred) at (0,0){
      \includegraphics{testred.pdf}
    };
    \draw let \p1 = (testred.west), \p2 = (testred.east) in
      node[inner sep=0,below=0mm of testred,text width={\x2-\x1}] (testgreen) {
        \includegraphics[height=\linewidth,angle=-90,origin=c]{testgreen.pdf}
      };
  \end{tikzpicture}
\end{document}

Notes:

This results with:

$ pdflatex montager.tex
...
$ pdfinfo montager.pdf | grep 'Page size' 
Page size:      350.398 x 776.074 pts

... which is not bad at all! And here is the image of the resulting PDF (pretty much the same as in OP):

montager-pdf.png

... which I obtained with:

convert -density 72 montager.pdf montager-pdf.png

Looks pretty much as I wanted it to - so I'm back to being happy again :)
Cheers!

Related Question