Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I have multiple images in a row (using floatrow) and would like to scale them, that they fill the row, while their top and bottom edges are flush to each other, and the aspect ratio of the images them self is kept. Note that I have arbitray aspect ratios. Poking arround I found that I could get the images sizes and based on that do some calculations.

However doing this from hand seems tiresome (include the image in a savebox, get the widths, run them through formulas, insert them with scalefactors), and automateable. Is there a package to do so? (I am using floatrow, to place images side by side)

share|improve this question
1  
I edited my answer below to reflect the syntax of the latest scalerel package (1.5). When I wrote my original answer (not from my usual workplace), I apparently had an older version. The type of nesting I did in my \sbox syntax no longer worked. I have revised my answer to reflect this, and the fact that you didn't complain about it must mean you have an older version too. Please update to V1.5 –  Steven B. Segletes Jul 31 '13 at 15:45

2 Answers 2

up vote 3 down vote accepted

Without addressing the specifics of floatrow, about which I know nothing, your problem has two components: scaling the figures to the same height, and scaling the overall width to some dimension, such as \textwidth. This MWE shows how to do both, using the scalerel package to match the height of one object to the next (while preserving the aspect ratio). Then, I do a scale on the result to match the width to, in this case, \textwidth.

Where my figures are composed of \rules, yours would be composed of tikz images. Note also that \scalerel assumes its arguments are in math mode, and so I include the math delimiters to, in essence, get out of math mode.

I placed all the figures side-by-side into a single box \x. However, if your requirements (for captioning, etc.) required you to keep the images as separate entities, \scalerel*{$\figa$}{$\figd$} would be the command to create a version of just \figa scaled to the size of \figd. You of course, would still have to \scalebox it by a factor of \scaleratio to get it to the desired final size (I show this case as my final example).

EDITED to be compatible with latest package (scalerel V1.5)

\documentclass{article}
\usepackage{scalerel}
\usepackage{fp}
\usepackage{stackengine}
\def\stacktype{L}
\usepackage{xcolor}
\begin{document}
\def\figa{\color{blue}\rule{.5in}{.7in}}
\def\figb{\color{red}\rule{.7in}{.3in}}
\def\figc{\color{green}\rule{.4in}{.5in}}
\def\figd{\color{black}\rule{1.in}{.8in}}

Figures as is:

\figa\figb\figc\figd

figures scaled to height of figd

\newsavebox\x
\sbox\x{\scalerel{$\figc$}{$\figd$}}
\sbox\x{\scalerel{$\figb$}{\usebox{\x}}}
\sbox\x{\scalerel{$\figa$}{\usebox{\x}}}
\usebox{\x}

textwidth rule

\rule[1ex]{\textwidth}{.1ex}


figures scaled to textwidth in one box

\newcount\figwidthc
\newcount\textwidthc
\figwidthc=\wd\x
\textwidthc=\textwidth
\FPdiv\scaleratio{\the\textwidthc}{\the\figwidthc}
\scalebox{\scaleratio}{\usebox{\x}}

individual figures scaled to textwidth

\stackunder{\scalebox{\scaleratio}{\scalerel*{$\figa$}{$\figd$}}}{(a)}%
\stackunder{\scalebox{\scaleratio}{\scalerel*{$\figb$}{$\figd$}}}{(b)}%
\stackunder{\scalebox{\scaleratio}{\scalerel*{$\figc$}{$\figd$}}}{(c)}%
\stackunder{\scalebox{\scaleratio}{\figd}}{(d)}
\end{document} 

enter image description here

share|improve this answer
    
I like this solution, and will fiddle a bit with the code later on. I pretty much need what you explained in the last example. I wonder if there are some further optimizations: 1.store the last figure (d) in a savebox, so it is not rendered every time I scale a, b and c 2.Store a, b, c as well, since you use them twice, once to determine the overall width (2 times, onc e to compare the scaled to height figures to textwidth, once to actually draw them) 3.can I somehow teach tex to calculate scaleratio automatically by simply putting only the last part (idividual figures) in a special env –  ted Jul 28 '13 at 7:55
    
Since only 3. is an issue for me I will start a follow up question. –  ted Jul 28 '13 at 7:56
    
link to followup: tex.stackexchange.com/q/125738/19326 better automatization of the process –  ted Jul 31 '13 at 15:55

Just scale the following pictures so that they have the same height as the first one and finally resize the row to be the width you want:

\documentclass{article}
\usepackage{graphicx,etoolbox}

\newenvironment{imageRow}[1][\textwidth]
 {\center\firstimagetrue\def\rowwidth{#1}}
 {\resizebox{\rowwidth}{!}{\addimagerow}\endcenter}

\newif\iffirstimage
\newlength{\imageheight}
\newcommand{\addimage}[1]{%
  \sbox0{\includegraphics{#1}}%
  \iffirstimage
    \setlength{\imageheight}{\ht0}%
    \appto\addimagerow{\includegraphics{#1}}%
    \firstimagefalse
  \else
    \appto\addimagerow{\includegraphics[height=\imageheight]{#1}}%
  \fi
}

\begin{document}

\begin{imageRow}
\addimage{example-image.pdf}
\addimage{example-grid-100x100pt.pdf}
\addimage{example-image-golden.pdf}
\end{imageRow}

\begin{imageRow}[.7\textwidth]
\addimage{example-image.pdf}
\addimage{example-grid-100x100pt.pdf}
\addimage{example-image-golden.pdf}
\addimage{example-image-16x9.pdf}
\end{imageRow}

\end{document}

enter image description here

The center environment is just for convenience.

This is not limited to \includegraphics; some changes may be needed to support other types of graphics such as TikZ pictures, but the idea is the same: so long that the images are vectorial, it's not a problem scaling them multiple times.

share|improve this answer
    
David Carlisle actually has a slightly simpler solution he gave in chat: chat.stackexchange.com/transcript/message/18495414#18495414, just scale all images to an arbitrary height (but equal), then scale the row. This skips the need to get the height for the first image. –  ted Nov 6 at 1:51
    
@ted I too thought of that, after posting my answer. I have a couple of ideas for improving it. –  egreg Nov 6 at 9:44

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.