我有一张图片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
如上所述,您需要在垂直方向上缩小盒子而不是将其填充。
答案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
。