Measure precisely the height of a figure and its caption

boxfloatsgraphicsheight

I would like to create a command that calculates the maximum size of a figure so that the figure and its caption do not overflow into the margins.

To do this, I save the caption in a box (\boxcaption), then I measure the height of the caption (\ht\boxcaption) and its depth (\dp\boxcaption). I deduce the maximum height of the figure which should be : \dimexpr \textheight -\abovecaptionskip -\ht\boxcaption -\dp\boxcaption.

However, there is still a small space above and below the image of the figure and the caption. Would you know where this space comes from?

enter image description here

Here is a MWE:

\documentclass{article}
\usepackage[showframe]{geometry}
\usepackage{graphicx, mwe, lipsum}
\newsavebox{\boxcaption}
\newcommand{\maxsizefigure}[2]{% #1 : image, #2 : caption
\begin{figure}[p]%
    \sbox{\boxcaption}{%
        \begin{minipage}{\textwidth}%
            #2%
        \end{minipage}%
    }%
    \centering%
    \includegraphics[width=\linewidth, height=\dimexpr \textheight -\abovecaptionskip -\ht\boxcaption -\dp\boxcaption, keepaspectratio]{#1}%
    #2%
\end{figure}%
}

\begin{document}
\maxsizefigure{example-image-9x16.png}{\caption{\lipsum[1]}}
\end{document}

Best Answer

UPDATED after follow-up question.

There are three steps: encapsulating the caption in the box \boxcaption, calculating the height available for the figure using the total height of \boxcaption, and finally typesetting the figure and caption.

Unlike the posted question, the box used to measure the caption is reused, and in that way the padding added by that environment is taken into account.

The code was tested with various font sizes.

a

b

\documentclass[10pt]{article}

\usepackage[showframe]{geometry}
\usepackage{graphicx, mwe, lipsum}

\newsavebox{\boxcaption}
\newcommand{\maxsizefigure}[2]{% #1 : image, #2 : caption
    \begin{figure}[p]%   
        \sbox{\boxcaption}{%
            \begin{minipage}{\linewidth}%
                #2%
                \addtocounter{figure}{-1}% added <<<<
            \end{minipage}%
        }%
        \centering%
        \includegraphics[width=\linewidth, height=\dimexpr \textheight -\ht\boxcaption -\dp\boxcaption, keepaspectratio]{#1}\par
        \usebox{\boxcaption}% insert the complete caption
    \end{figure}%
}

\begin{document}    

\maxsizefigure{example-image-9x16.png}{\caption{\fontsize{8}{10}\selectfont\lipsum[1] \textbf{Size= 8pt}}}

\maxsizefigure{example-image-9x16.png}{\caption{\fontsize{12}{14}\selectfont\lipsum[1] \textbf{Size= 12pt} }}

\maxsizefigure{example-image-9x16.png}{\caption{\fontsize{14}{17}\selectfont\lipsum[1] \textbf{Size= 14pt}}}

\maxsizefigure{example-image-9x16.png}{\caption{\fontsize{16}{19}\selectfont\lipsum[1] \textbf{Size= 16pt}}}

\end{document}