如何将 \includegraphics 缩放到精确的宽度和高度?

如何将 \includegraphics 缩放到精确的宽度和高度?

我有一张图片foo.jpg。我想将其缩放为一个精确大小的框,例如 100pt 宽 x 200pt 高。我可能想单独缩放轴,或者我可能想保留纵横比并用空格填充较短的尺寸。

但是,如果我使用\includegraphics[width=100pt,height=200pt]{foo.jpg},则生成的框并不正好是 100pt x 200pt,而是 99.9974pt x 199.99854pt。

我怎样才能将图形放入具有规定宽度和高度的框中?

有没有比在由 vfil/hfil 包围的 includegraphics 周围创建 vbox 和 hbox 更好的方法?

或者,\includegraphics 是否可能超过规定的宽度和高度,需要使用 vss/hss?

\documentclass{standalone}

\usepackage{graphicx}

\newsavebox{\badbox}
\newsavebox{\goodbox}
\newlength{\mywidth} \setlength{\mywidth}{100pt}
\newlength{\myheight} \setlength{\myheight}{200pt}

\begin{document}
\typeout{mywidth=\the\mywidth, myheight=\the\myheight}%
\sbox{\badbox}{%
  \includegraphics[width=\mywidth,height=\myheight]
    {foo.jpg}}%
\sbox{\goodbox}{%
  \vbox to\myheight{%
    \vfil%
    \hbox to\mywidth{\hfil\usebox{\badbox}\hfil}%
    \vfil}}%
\typeout{badbox wd=\the\wd\badbox, ht=\the\ht\badbox, dp=\the\dp\badbox}%
\typeout{goodbox wd=\the\wd\goodbox, ht=\the\ht\goodbox, dp=\the\dp\goodbox}%
\end{document}

输出:

mywidth=100.0pt, myheight=200.0pt
badbox wd=99.9974pt, ht=199.99854pt, dp=0.0pt
goodbox wd=100.0pt, ht=200.0pt, dp=0.0pt

输出keepaspectratio

mywidth=100.0pt, myheight=200.0pt
badbox wd=99.9974pt, ht=115.57187pt, dp=0.0pt
goodbox wd=100.0pt, ht=200.0pt, dp=0.0pt

答案1

你不需要有所有的嵌套盒子和胶水组合,你只需声明盒子大小即可

\documentclass{article}

\usepackage{graphicx}

\newsavebox{\badbox}

\newlength{\mywidth} \setlength{\mywidth}{100pt}
\newlength{\myheight} \setlength{\myheight}{200pt}

\begin{document}
\typeout{mywidth=\the\mywidth, myheight=\the\myheight}%
\sbox{\badbox}{%
  \includegraphics[width=\mywidth,height=\myheight]
    {example-image}}%

\typeout{badbox wd=\the\wd\badbox, ht=\the\ht\badbox, dp=\the\dp\badbox}%
\ht\badbox=\myheight \wd\badbox=\mywidth
\typeout{badbox wd=\the\wd\badbox, ht=\the\ht\badbox, dp=\the\dp\badbox}%




\end{document}

生产

badbox wd=99.99736pt, ht=200.00575pt, dp=0.0pt
badbox wd=100.0pt, ht=200.0pt, dp=0.0pt

我确实考虑过(很久以前)将其作为默认行为,但对于height=(和类似的\resizebox)来说,返回带有舍入误差的计算大小而不是请求的大小似乎略好一些。

之所以这样做,是因为大多数后端实际上无法将内容设置为指定的大小,只能缩放。请求的大小在用户界面上很方便,但这意味着 tex 必须计算所需的缩放因子。

graphicx使用 TeX 维度算法,该算法仅能够存储大约 5 位小数的值,并在计算中丢失一些小数,因此这里您会看到小数点后第三位的差异,但 0.00264pt 实际上不是很大。

如今,它可以使用更精确(且占用大量内存)的计算方法,例如l3fp使用十进制浮点数的函数,精度更高,大约有 18 位有效数字,但即便如此,你也无法保证实际的X (请求/实际的)完全等于请求因此如果您输入如上所述的值,您可能会得到 100.0000000000001pt 或类似的值,因此您可能仍希望强制该框为所请求的大小。


请注意,如果您确实使用了胶水,则不应使用,\vss这样\vfil它就可以缩小到负尺寸,请注意example-image如上所述,您需要在垂直方向上缩小盒子而不是将其填充。


也可以看看https://github.com/latex3/latex2e/issues/112

答案2

拿大卫的答案并用 重新编码l3graphics,我们得到类似

\documentclass{article}

\usepackage{l3graphics}
\ExplSyntaxOn
\keys_define:nn { graphics }
  {
    height .dim_set:N = \l__graphics_height_dim ,
    width .dim_set:N  = \l__graphics_width_dim ,
  }
\box_new:N \l__graphics_tmp_box
\NewDocumentCommand \includegraphics { O{} m }
  {
    \mode_leave_vertical:
    \group_begin:
       \keys_set_known:nn { graphics } {#1}
       \hbox_set:Nn \l__graphics_tmp_box
         { \graphics_include:nn {#1} {#2} }
       \box_resize_to_wd_and_ht_plus_dp:Nnn \l__graphics_tmp_box
         \l__graphics_width_dim \l__graphics_height_dim
       \box_use:N \l__graphics_tmp_box
    \group_end:
  }
\ExplSyntaxOff


\newsavebox{\badbox}

\newlength{\mywidth} \setlength{\mywidth}{100pt}
\newlength{\myheight} \setlength{\myheight}{200pt}

\begin{document}
\typeout{mywidth=\the\mywidth, myheight=\the\myheight}%
\sbox{\badbox}{%
  \includegraphics[width=\mywidth,height=\myheight]
    {example-image.pdf}}%

\typeout{badbox wd=\the\wd\badbox, ht=\the\ht\badbox, dp=\the\dp\badbox}%
\ht\badbox=\myheight \wd\badbox=\mywidth
\typeout{badbox wd=\the\wd\badbox, ht=\the\ht\badbox, dp=\the\dp\badbox}%




\end{document}

请注意,目前仅l3graphics用于低级图形包含,并不直接涵盖调整大小:需要更好的界面来完全替代\includegraphics

相关内容