149

How can I vertically center two images next to one another? Here is some example code:

\begin{minipage}[h]{6in}
  \centering
   \vspace*{.3in}~\\
   \includegraphics[height=1.25in]{fig1.pdf}
   \hspace*{.2in}
   \includegraphics[height=1in]{fig2.pdf}
\end{minipage}

I want the center line of both images to be at the same height.

Chris Cannon
  • 1,745

8 Answers8

169

The baseline of images is at their bottom. You could change that by using \raisebox. For example:

\documentclass{article}
\usepackage[textwidth=6in]{geometry}
\usepackage[demo]{graphicx}
\begin{document}
\noindent
\begin{minipage}{6in}
  \centering
  \raisebox{-0.5\height}{\includegraphics[height=1.25in]{fig1.pdf}}
  \hspace*{.2in}
  \raisebox{-0.5\height}{\includegraphics[height=1in]{fig2.pdf}}
\end{minipage}
\end{document}

Gives vertically centered images, here black rectangles because of the demo option:

alt text

Raising their baseline by .5\height has the nice effect that also following text would be aligned at the new baseline at the vertical center.

Alternatively, you could use \vcenter, which is working fine as well:

\begin{minipage}{6in}
  \centering
  $\vcenter{\hbox{\includegraphics[height=2.25in]{fig1.pdf}}}$
  \hspace*{.2in}
  $\vcenter{\hbox{\includegraphics[height=1in]{fig2.pdf}}}$
  following text
\end{minipage}

Note: \vcenter requires mathmode. \hbox for the argument may be necessary too.

Stefan Kottwitz
  • 231,401
62

The graphbox package adds an "align" option to the \includegraphics command that makes this very easy:

\usepackage{graphicx}
\usepackage{graphbox}
[...]

\begin{minipage}{6in}
  \centering
  \includegraphics[align=c,height=1.25in]{fig1.pdf}
  \hspace*{.2in}
  \includegraphics[align=c,height=1in]{fig2.pdf}
\end{minipage}
Grodriguez
  • 1,149
20

Just use \parboxes. Let's say we want two include the two jpg files: first picture and second picture The following code does it:

\documentclass{article}
\usepackage{graphicx}

%% first attempt (but needs modifications in case of optional parameters to \includegraphics)

\newcommand{\vcenteredinclude}[1]{\begingroup
\setbox0=\hbox{\includegraphics{#1}}%
\parbox{\wd0}{\box0}\endgroup}

%% better: (general command to vertically center horizontal material)
\newcommand*{\vcenteredhbox}[1]{\begingroup
\setbox0=\hbox{#1}\parbox{\wd0}{\box0}\endgroup}

\begin{document}

How can I vertically center two images next to one another? I want the center
line of both images to be at the same height.

\vcenteredhbox{\includegraphics{figure1.jpg}} and
\vcenteredhbox{\includegraphics{figure2.jpg}} and \vcenteredhbox{\LARGE This too
is vertically centered}

\end{document}

The result of the pdflatex compilation is: outcome of pdftex run

  • Could you explain how your \vcenteredinclude works? – doncherry May 01 '11 at 16:59
  • 1
    @doncherry: Well, the LaTeX \parbox macro by default centers its content respective to the surrounding baseline. But it has a mandatory argument to specify its width. Contrarily to other LaTeX macros such as \makebox or \raisebox there is no automatic setting of a macro \width to refer to the width of the enclosed material (indeed, there is no such natural width as it is destined to be specified by the user). So I just use the most basic TeX primitives dealing with boxes to get this width and pass it to \parbox as its first mandatory argument. –  May 02 '11 at 07:12
  • I have edited my code to add a better, general purpose command, \vcenteredhbox which uses \parbox to typeset horizontal material in a vertically centered manner relative to the surrounding baseline. –  May 02 '11 at 10:43
  • \vcenter is a primitive and faster than \parbox. – Ahmed Musa Dec 06 '11 at 15:41
  • 1
    @AhmedMusa I am not sure you are still around, thus leaving this (belated) comment for passers-by. Yes I confirm I probably didn't know about \vcenter in May 2011. I recall dimly having attracted a bit of criticism in some other answer, where I used \vcenter, perhaps in 2013 or 2014. The reproach was that "it is not a documented LaTeX command". –  Feb 10 '16 at 13:42
8
% Declare a dedicated box, because temporary boxes may be busy:
\cptnewvariables{box}[vcp@box]{a}
% Declare unique keys for the command \vcenterprocess. We could have done
% this using a key command or key environment, or even pathkeys.
\ltxkeys@declarekeys*[KVA]{xwmvcenter}[vcp@]{%
  cmd/\needvalue{processor}/\@firstofone;
  cmd/fileext/pdf;
  cmd/inputpath/.;
  cmd/separation/.25cm;
  % Set the alignment of the graphics or text:
  choice/align.{%
    center/.code=\def\vcp@align{center},
    left/.code=\def\vcp@align{flushleft},
    right/.code=\def\vcp@align{flushright},
    justified/.code=\def\vcp@align{relax}%
  }/center;
}
\robust@def*\vcenterprocess{\cpt@testopt\xwm@vcenterprocess{}}
% #1=keys, #2=attributes. The presence of 'fig=' in #2 means
% that we have a graphics; 'text=' implies that this is a plain
% text.
\robust@def*\xwm@vcenterprocess[#1]#2{%
  \ltxkeys@setkeys[KVA]{xwmvcenter}{#1}%
  \ifpdf
    % PDF can handle many image formats:
    \xifinsetTF\vcp@fileext{,pdf,png,jpeg,jpg,mps,}%
      {}{\def\vcp@fileext{pdf}}%
  \else
    \def\vcp@fileext{eps}%
  \fi
  \def\xwm@tempa{0pt}%
  \setbox\vcp@boxa=\hbox{%
    % We can do some calculations inside the box.
    % Loop over all the submitted items. If #2 is a macro,
    % then the attributes have been put in a macro
    % by the user, in which case we need to expand the macro
    % at least one step.
    \edef\reserved@a{\cptdocommalist\ifmacroTF{#2}{*}{}}%
    \reserved@a{#2}{%
      % Split the attributes, so that we know whether a file
      % or plain text has been given; and to get filename, viewport, etc.
      \ltxkeys@simplesplitkeyval{##1}%
      % The inputpath normally contains outer braces. The image or text
      % attributes too might have outer braces. Remove outer braces here.
      \xwm@stripallbrincs\vcp@inputpath
      \xwm@stripallbrincs\key@value
      \oifstrcmpTF{text}\key@name{%
        \xwm@swatrue
      }{%
        \xwm@swafalse
        % The keys and attributes might contain active commas, active equality
        % sign (babel), etc. They may also contain double commas, equals, and
        % spurious spaces. So normalize the key-val list here.
        \kv@@normalize*\key@value
        \xifinsetTF{,\detokenize{file=}}{,\cptoxdetok\key@value}{%
          \def\reserved@a####1,file=####2,####3\xwm@nil{%
            \def\vcp@filename{####2}%
            \def\vcp@figattr{####1,####3}%
            % Splitting might have introduced double, leading or trailing commas, and
            % spurious spaces. So normalize the csv list here.
            \csv@@normalize*\vcp@figattr
          }%
          \expandafter\reserved@a\expandafter,\key@value,\xwm@nil
        }{%
          \xwm@err{No filename in second argument of
            \string\vcenterprocess}\@ehc
        }%
      }%
      % Set the graphics input path. We can hack directly into graphics package's 
      % input path mechanism here because we're in a local group.
      \edef\Ginput@path{\ifcsnullTF\vcp@inputpath{}{{\vcp@inputpath/}}}%
      \hspace*{\xwm@tempa}%
      \cptexpanded{%
        \ifxwm@swa
          $\vcenter{\hbox{\noexpand\vcp@processor{\key@value}}}$%
        \else
          $\vcenter{\hbox{\noexpand\includegraphics
            [\vcp@figattr]{\vcp@filename.\vcp@fileext}}}$%
        \fi
      }%
      \let\xwm@tempa\vcp@separation
    }%
  }%
  \begin{\vcp@align}%
  \quitvmode\unhbox\vcp@boxa
  \end{\vcp@align}%
}

\documentclass{article}
% CTAN's xwatermark needs updating:
\usepackage{xwatermark}
\usepackage[left=2cm,right=2cm,bottom=4cm]{geometry}
\usepackage{ifpdf}
\usepackage{graphicx}
% Example (create your own document and garbage text).
% \garbagetext is a private garbage generator.
\def\mygraphics{%
  fig   ={file=comet1, viewport=20 21 590 400, scale=.1},
  fig   ={file=comet1, viewport=20 21 590 400, scale=.08},
  text  ={This too is vertically centered}
}
\thispagestyle{empty}
\garbagetext[3]
\vcenterprocess[
  inputpath={./graphics},
%  fileext=jpeg,
  align=left,
  processor=\textbf
]{\mygraphics}
\garbagetext
\vcenterprocess[
  inputpath={./graphics},
  align=center,
  processor=\textbf
]{\mygraphics}
\garbagetext
\vcenterprocess[
  inputpath={./graphics},
  align=right,
  processor=\textbf
]{\mygraphics}
\garbagetext

enter image description here

Ahmed Musa
  • 11,742
  • I reduced the size of the image. I hope you didn't mind. – percusse Dec 09 '11 at 04:51
  • I don't know how to do it here. Please teach me. – Ahmed Musa Dec 09 '11 at 05:28
  • Actually I downloaded the image, cropped it and re-uploaded. So, not much to teach :) – percusse Dec 09 '11 at 05:33
  • 2
    @percusse, Ahmed Musa: A couple of different ways to crop images / PDFs were discussed at http://meta.tex.stackexchange.com/questions/1799/how-do-you-crop-an-attached-pdf – Jake Dec 09 '11 at 05:40
  • 1
    @AhmedMusa This is an excellent answer, but maybe a bit rather complicated for the average user of this site. Won't you please add a bit of explanation either in the code or the answer itself and there is no reason why you shouldn't trump up ltxkeys a bit, its an excellent package. – yannisl Dec 09 '11 at 10:00
  • @Yiannis Lazarides: I think I should just include it in the xwatermark package, with explanations in the user guide. But TeX is only one item in a crowded basket. BTW, the ltxkeys on CTAN may not compile right now because I changed aspects of catoptions, on which ltxkeys depends, a bit and uploaded it prematurely 2 days ago. I need to upload the latest version of ltxkeys soonest. – Ahmed Musa Dec 11 '11 at 07:03
  • @AhmedMusa -- Good idea, about having it in the user manual. Keep up the good posts:) – yannisl Dec 11 '11 at 07:28
7

Embed the figure into a tabular cell which is vertically aligned inline (in contrast to a figure).

\documentclass{article}
\usepackage[textwidth=6in]{geometry}
\usepackage[demo]{graphicx}
\begin{document}

line before\\
line before\\
text before
\begin{tabular}{@{}c@{}}{\includegraphics[height=1.25in]{fig1.pdf}}\end{tabular}
text between
\begin{tabular}{@{}c@{}}{\includegraphics[height=1in]{fig2.pdf}}\end{tabular}
text after\\
line after\\
line after

\end{document}

@{} removes the column padding.

ShreevatsaR
  • 45,428
  • 10
  • 117
  • 149
Friedrich
  • 71
  • 1
  • 1
7

I find ConTeXt's syntax for image combinations to be much cleaner. I wish some LaTeX package provided a similar interface.

\useMPlibrary[dum] % for dummy images
\definecombination[middle][location=middle]
\starttext
  \startcombination[middle][2*1]
    {\externalfigure[dummy][width=4cm,height=5cm]}{}
    {\externalfigure[dummy][width=5cm,height=3cm]}{}
  \stopcombination
\stoptext

which gives

enter image description here

You can change location=middle to location=high or location=low to get top and bottom aligned images.

Aditya
  • 62,301
4

A sidebyside tcolorbox was missing from these solutions. It vertically centers both sides by default.

Needed package: https://www.ctan.org/pkg/tcolorbox

Package documentation: https://ctan.tetaneutral.net/macros/latex/contrib/tcolorbox/tcolorbox.pdf

\documentclass{article}
\usepackage[textwidth=6in]{geometry}
\usepackage[most]{tcolorbox}
\usepackage{lipsum}

\begin{document}

\begin{tcolorbox}[sidebyside, blanker, halign=center, halign lower=center] \includegraphics[width=.9\textwidth]{example-image} \tcblower \includegraphics[width=.6\textwidth]{example-image} \end{tcolorbox}

\end{document}

enter image description here

Drarig29
  • 103
  • 4
Ignasi
  • 136,588
4

Use trimming of one figure in a negative way (negative value for 'trim').

An easy, but dirty way to achieve a more vertical alignment is by 'negatively' trimming your figure. This has the advantage that your subcaptions ((a) and (b)), when using the subfigure package, remain aligned and do not vertically move with the alignment of the figures.

\begin{figure}  
\subfigure[subcaption (a)]{\includegraphics[width = 0.4\linewidth]{image_a.jpg}} \hspace{3ex}  
\subfigure[subcaption (b)]{\includegraphics[width = 0.4\linewidth, trim = 0cm -2cm 0cm 0cm]{image_b.jpg}}  
\caption{caption text here.}  
\end{figure}

The negative value for the 'bottom'-input for 'trim' causes the second figure to move upward by 2cm (in this case).

Andre
  • 41