Automatically fit the graphics in the remaining space of a Beamer slide

One way is to define a new command which takes as arguments the frame content before the image, the file name of the image and, optionally, any frame content following the image. So that these can be specified in their natural order, I use xparse's \NewDocumentCommand to define

\fitimage{<content before>}{<image file name>}[<content after>]

This command calculates the total height of a paragraph box containing the first and third arguments (\fitotherht). It then calculates an appropriate maximum height for the image (\fitimageht) by subtracting this from \textheight and making a few adjustments to allow room for the vertical spacing at the head and foot of the frame, and for some space between the different clusters of content within the frame.

Code:

\documentclass{beamer}
\usepackage[pangram]{blindtext}
\usetheme{Pittsburgh}
\usepackage{xparse,calc}
\newlength\fitimageht
\newlength\fitotherht
\newsavebox\fitimagebox
\NewDocumentCommand \fitimage { m m O {} }{%
  \sbox\fitimagebox{%
    \parbox{\textwidth}{%
      #1\par
      #3
    }%
  }%
  \settototalheight{\fitotherht}{%
    \usebox\fitimagebox
  }%
  \setlength\fitimageht{\textheight}%
  \addtolength\fitimageht{-\fitotherht-\topskip-\footskip-3\baselineskip}%
  #1\par
  \centering
  \includegraphics[width=\textwidth,height=\fitimageht,keepaspectratio]{#2}\par
  #3}
\begin{document}

\begin{frame}
  \fitimage{%
    \frametitle{Something}
    \blindenumerate[2]
  }{2000px-If-then-else-control-flow-graph}
\end{frame}

\begin{frame}
  \fitimage{%
    \frametitle{Something}
    \blindenumerate[2]%
  }{2000px-If-then-else-control-flow-graph}[%
    \blinddescription[2]
  ]
\end{frame}

\begin{frame}
  \fitimage{%
    \frametitle{Something}
    \blindenumerate[6]%
  }{2000px-If-then-else-control-flow-graph}[%
    \blinddescription[2]
  ]
\end{frame}

\end{document}

fit-my-image

It is important that all frame content be included within the arguments to the command. So this won't work with overly fragile content. (I imagine verbatim code would not work, for example.) But for ordinary text, frame title etc., it seems to do a reasonable job. If the spacing I've chosen is not to your taste, you can easily adjust the value of \fitimageht by subtracting more or less as applicable.

This does not result in any bad boxes, according to the log file.


Following code shows an alternative solution using tcolorbox package and its space to option.

space to = macro saves (after several compilations: two or more) into macro the difference between box contents natural height and box forced height. This difference can be used to fix the graphic height filling, this way, all the available space.

As a fixed height is needed for this kind of tcolorboxes and I don't know how to automatically compute it, I've used height=.8\textheight.

Then a declaration like

\begin{tcolorbox}[enhanced,height=.8\textheight, space to=\myspace]
... 
{\par\centering\includegraphics[height=\myspace]{example-image}\par}
\end{tcolorbox}

will build a tcolorbox with height .8\textheight and the available vertical space will be stored in \myspace which is used to fix graphics size.

Following code shows some examples with default tcolorboxes and some more with a blankest style which creates a box like regular text:

\documentclass{beamer}
\usepackage[pangram]{blindtext}
\usetheme{Pittsburgh}
\usepackage[most]{tcolorbox}

\newtcolorbox{myfitbox}[1][]{
    enhanced,
    height=.8\textheight,
    space to=\myspace,
    #1}

\begin{document}

\begin{frame}
\frametitle{Something}
\begin{myfitbox}
\blindenumerate[2]
{\par\centering\includegraphics[height=\myspace]{example-image}\par}
\end{myfitbox}
\end{frame}

\begin{frame}
\frametitle{Something}
\begin{myfitbox}
\blindenumerate[2]
{\par\centering\includegraphics[height=\myspace]{example-image}\par}
\blinddescription[2]
\end{myfitbox}
\end{frame}

\begin{frame}
\frametitle{Something}
\begin{myfitbox}
\blindenumerate[6]
{\par\centering\includegraphics[height=\myspace]{example-image}\par}
\blinddescription[2]
\end{myfitbox}
\end{frame}

\begin{frame}
\frametitle{Something}
\begin{myfitbox}[blankest]
\blindenumerate[2]
{\par\centering\includegraphics[height=\myspace]{example-image}\par}
\end{myfitbox}
\end{frame}

\begin{frame}
\frametitle{Something}
\begin{myfitbox}[blankest]
\blindenumerate[2]
{\par\centering\includegraphics[height=\myspace]{example-image}\par}
\blinddescription[2]
\end{myfitbox}
\end{frame}

\begin{frame}
\frametitle{Something}
\begin{myfitbox}[blankest]
\blindenumerate[6]
{\par\centering\includegraphics[height=\myspace]{example-image}\par}
\blinddescription[2]
\end{myfitbox}
\end{frame}
\end{document}

enter image description here