【注】笔记来自《LaTeX入门》——刘海洋。
1. 简介
插图功能是利用 TeX 的特定编译程序提供的机制实现的,不同的编译程序支持不同的图形方式。不同 LaTeX 编译程序对应的插图格式如下表所示:
TeX 引擎命令 | 图形驱动 | 支持的格式 | 说明 |
---|---|---|---|
latex | Dvips | EPS | MiKTeX 还部分支持 PNG 和 JPEG |
latex | DVIPDFMx | EPS,PDF,PNG,JPEG | PDF、PNG、JPEG 需要使用 extractbb 程序生成 .xbb 文件 |
pdflatex | −-− | MPS、PDF、PNG、JPEG | MPS 是 METAPOST 的输出格式,TeXLive 2010 以后还能自动将 EPS 转换为 PDF 文件产插入 |
xelatex | xdvipdfmx | EPS、PDF、PNG、JPEG、BMP | 驱动是自动调用的,MAC 系统下的旧驱动 xdv2pdf 还支持其他一些格式 |
由上表可知,除非使用传统的 Dvips 程序作为图形驱动,一般编译程序支持的图形格式都有好几种,实际插入图形格式也就有不同的选择。对于 pdfLaTeX、XeLaTeX 这些现代的常用编译程序来说,PDF、PNG、JPEG 这三种格式是更为常用的,它们的用途也各自不同:
- PDF图片通常用来作为矢量图形的标准格式。矢量图形可以以任意比例放缩而不影响输出效果,在表现固定图案或数据产生的图形时很有优势。在以前 LaTeX 更多使用 EPS 格式的矢量图形,不过由于现在支持输出 PDF 的作图软件变得更加普及,而且 PDF 格式的文件通常比相同内容的 EPS 图形体积小,功能(如透明色)也更多。一般的矢量图设计软件(如 Illustrator、CorelDraw、Inkscape)、专业数学软件(如 MatLab、Maple、Mathematica)、计算或作图语言(如 R、GNUplot)、图论或流程图工具(如 Visio、Dia、Graphviz)、物理化学或工程图工具(如 JaxoDraw、ChemDraw、AutoCAD)等,都可以保存或打印为 PDF 格式的图片共 LaTeX 使用。
- PNG 图片是无损压缩的像素图格式。通常用来显示计算机制作的非自然图形,如复杂数据可视化结果。一般能输出矢量图的软件也都可以输出 PNG 格式的像素图,也有一些科技作图软件不支持矢量图的。通常数据可视化的图形最好使用矢量图格式,不多对于一些特殊情形,如逐点产生的动力系统图像、3D CG 图,还是更适合使用 PNG 格式。
- JPEG 图片是有损压缩的像素图格式。通常用作照片的格式。计算机产生的非自然图像最好不要使用这种有损压缩格式。
2. 基础
在 LaTeX 中,插图是由 graphics
或 graphicx
宏包所使用的 includegraphics
命令完成的。graphics
宏包和 graphicx
宏包在功能上并没有什么差别。graphicx
宏包支持 <项目>=<值>
的语法,使用起来更为方便,功能也更为强大。
graphicx
宏包可以使用 draft
和 final
选项,用来表示是否实际插图。当宏包使用 draft
选项,或是文档使用全局的 draft
选项时,includegraphics
命令并不会实际插入图形,而只是得到一个与图形大小相同的带有文件名的方框,这个选项对于未完成的草稿可以在一定程度上加快编译,并减小文件大小。当文档完成时,就可以更改 draft
选项为 final
选项,得到最终的文档。
usepackage[draft]{graphicx}
% 导言区
% ……
includegraphics{picture}
graphicx
宏包还有一个特别有用的命令 graphicspath
,它可以指定图形文件的搜索目录列表,不同的目录用分组隔开:
graphicspath{{figures/}} % 指定图片路径
graphicspath{{pdf/}{png/}{jpg/}} % 指定不同类型图片路径
2.1 格式
插图的核心命令是 includegraphics
,其语法格式为:
includegraphics[<选项>]{<文件名>}
其中,<文件名>
是图形文件的文件名,一般的扩展名可以省略不写,LaTeX 会自动查找它支持的文件格式,为了明确也可以加上扩展名。
2.2 大小、位置
插入的图形一般都有一个自然比例,对于 EPS、PDF 图形就是制作的尺寸,对于 JPG、PNG、BMP 等像素图的尺寸则是点阵数除以图形打印度(一般用每英寸点数 DPI 表示)。可以给 includegraphics
命令加一些可选项来调整图形的大小、位置等:
includegraphics[width=2em]{picture} % 宽度
includegraphics[height=1cm]{picture} % 高度
includegraphics[scale=0.5]{picture} % 缩放比例
2.3 旋转
使用 angle
选项可以让图形逆时针旋转一定角度,旋转中心可以用 origin
选项确定。origin
的值可以用字符 l,r,c,t,b,B
中的一个或两个,分别表示左、右、中、上、下和基线(默认值为 lb
)。
includegraphics[angle=90]{picture} % 以左下角为原点逆时针旋转 90 度
includegraphics[angle=-45,origin=c]{picture} % 以中心点为原点顺时针旋转 45 度
插入图形的基线就在图片的底部,因而图片盒子的深度为零。但图片旋转时,基线和深度会随 origin
不同而变化,此时要对图片进行放缩,就要用 totalheight
代替 height
选项,表示规定图片深度和高度之和:
includegraphics[angle=90,origin=b,totalheight=1.5cm]{picture}
2.4 其他
includegraphics
除了以上介绍的参数选项外,还有一些其他的参数选项,诸如:
draft
、final
:同宏包选项相同,仅针对当前插图keepaspectratio
:布尔值,决定缩放时是否保持图片原有的长宽比。如果只设置了width
、height
或totalheight
中的一个,则默认为真。
对于更多的参数选项,可参见 graphicx
宏包官方文档。
texdoc graphicx
3. 进阶
3.1 几何变换
graphicx/graphics
宏包不仅提供了插图的功能,也提供了对任意对象(即盒子)进行几何变换的功能。除了平移,TeX 本身并没有几何变换的功能,这些功能同样是依赖具体的编译程序。
scalebox
命令用来按比例对内容进行放缩,其语法格式为:
scalebox{<水平因子>}[<垂直因子>]{<内容>} % <垂直因子> 省略时,与 <水平因子> 相同。
reflectbox
命令用来对内容做水平镜像反射,其语法格式为:
reflectbox{<内容>} % 相当于 scalebox{-1}[-1]{<内容>}
resizebox
命令用来把内容放缩到指定的宽度和高度,其语法格式为:
resizebox{<宽度>}{<高度>}{<内容>} % <宽度> 和 <高度> 可以使用 ! 表示按比例随另一个分量放缩
-
resizebox*
命令和resizebox
功能相同,只是第二个参数表示盒子高度和深度之和。 -
rotatebox
命令用来对内容进行旋转,其语法格式为:
rotatebox[<选项>]{<角度>}{<内容>} % <选项> 是 graphicx 宏包才有
rotatebox
命令在选项中可以使用 origin
选项表示旋转原点,值与 includegraphics
中的选项相同,使用 lrctbB
中的一个或两个;也可以使用 x=2mm,y=5mm
这样的选项准确指定旋转原点。此外,还可以使用 units
选项,其表示旋转的单位,默认值为 1∘1^circ1∘,设置 units=6.283185
就相当于使用弧度制。
【注】graphicx
宏包并不提供错切变换的功能,如有需要,可以使用 PSTricks
、tikz
等绘图宏包。
3.2 页面旋转
在 LaTeX 中,不仅可以对盒子进行旋转,也可以对整个页面的内容进行旋转。lscape
宏包的 landscape
环境就可以把整个页面逆时针旋转 90∘90^circ90∘:
usepackage{lscape}
% 导言区
% ……
begin{landscape}
subsection{页面旋转}
……
end{landscape}
在生成 PDF 文件的情况下,可以使用 pdflscape
宏包代替 lscape
宏包,它可以在旋转页面的同时,让输出的 PDF 文件的页面在阅读器中显示时同时顺时针旋转 90∘90^circ90∘。
landscape
环境旋转的页面不会影响版心外面页眉页脚的输出,它通常用来表示过宽的内容,如大幅的图片或宽大的表格。不过,landscape
环境会在前后造成额外的分页,这对于只想单纯插入一张图片的情形往往并不适合。理想的办法是产生旋转的浮动环境,可以使用 rotfloat
宏包提供的 sidewapsfigure
来插入浮动的图形,同时不会影响浮动页前后的内容。rotfloat
宏包基于 rotating
宏包和 float
宏包,它会将所有浮动环境增加一个 sideways
开头的旋转环境(比如表格有 sidewapstable
环境)。
usepackage{rotfloat}
begin{sidewaysfigure}[p]
centering
includegraphics[width=7in]{figure}
caption{这是一张旋转的图片}
end{sidewaysfigure}
此外,可以给 rotfloat
宏包加上旋转方向选项(默认逆时针旋转):
usepackage[figureleft]{rotfloat} % 顺时针旋转
usepackage[figureright]{rotfloat} % 逆时针旋转
3.3 浮动体
详情参见 LaTeX浮动体。
3.4 标题控制
详情参见 LaTeX标题控制。
3.5 并排与子图
在实际中,经常需要把好几个图表并列放在一起输出。由于 LaTeX 的浮动环境并不对环境内容加以限制,所以可以直接把多个图表放在一个浮动体里。又因为 tabular
环境生成的表格和 includegraphics
插入的图形都是一个大盒子,因此可以直接并排放在一起。
begin{figure}
centering
caption{并排的图片}
includegraphics{picture1}
includegraphics{picture2}
end{figure}
如果是和一段文字并排放在一起,则可以使用 parbox
命令或 minipage
环境生成一个子段盒子:
begin{figure}
centering
includegraphics{picture}
qquad
parbox[b]{0.4textwidth}{这是一段和图片并排的文字内容。}
caption{picture}
end{figure}
使用并排的图表或文字时,需要注意其对齐方式。
tabular
环境和parbox
生成的子段盒子,默认都是在盒子中央对齐,盒子的基准点是中线左端。includegraphics
插入的图形其基准点在左下角。
因此上面例子中 parbox
使用了 b
选项使文字与前面的图形对齐,即「底部对齐」。如果需要让插入垂直「居中对齐」,则可以把它放进子段盒子中。对于「顶部对齐」,需要注意的是如果直接把插图放进 t
选项的子段盒子中,并不能使图片在顶部对齐,这是因为 t
选项只能让第一行按基线对齐;此时可以在盒子中先使用 vspace{0pt}
增加一个高度为 000 的空行,然后按这个空行对齐。
begin{figure}
centering
parbox[t]{0.4textwidth}{
vspace{0pt}
includegraphics{picture}
}
qquad
parbox[t]{0.4textwidth}{
vspace{0pt}
这是一段和图片并排的文字内容。
}
end{figure}
3.6 文字绕排
对于小幅的图表,使用绕排的方式可以得到更为紧凑的页面,在篇幅紧张或注重行文的场合,效果往往比浮动环境更有吸引力。由于 TeX 固有的限制,文字绕排的效果还无法做到尽善尽美,对绕排图表的位置、形状、使用都有一些限制。因此在使用绕排工具时,往往需要仔细的调整,或者另寻它途。
- 在 TeX 内部,绕排工具都是使用
parshape
命令的功能配合复杂的盒子操作与计算完成的,这也是为什么在列表环境中无法正常使用绕排功能(因为列表项也是由parshape
实现的)。 - 可以使用
parshape
命令产生复杂形状的绕排效果,下面所介绍的picinpar
、wrapfig
和floatflt
宏包都只能产生矩形的空洞,而shapepar
和cutwin
宏包则部分实现了复杂绕排的功能。
3.6.1 picinpar
宏包
picinpar
宏包提供了 figwindow
和 tabwindow
来实现绕排功能。它们的语法格式如下:
% 下面四个参数都是必选的
begin{figwindow}[<下降行数>,<水平位置>,<图内容>,<图标题>]
<绕排文字>
end{figwindow}
begin{tabwindow}[<下降行数>,<水平位置>,<表内容>,<表标题>]
<绕排文字>
end{tabwindow}
figwindow
和 tabwindow
环境会在 <绕排文字>
的段落中开一个窗口,用来放置图表。图表的位置由前两个参数确定,<下降行数>
是一个整数,确定被绕排图表的垂直位置,图表将在这么多行文字下方显示;<水平位置>
可以是 l,c,r
,表示窗口开在段落左、中、右的位置。后面两个参数分别是图表的内容和标题。标题可以留空,但需要保留标题前的逗号,此时就没有标题和编号。如果标题的编号需要引用,可以把标签放在标题内。
% 导言区
usepackage{picinpar}
% ……
begin{figwindow}[2,c,includegraphics{picture},picturelabel{fig:picture}]
lipsum*[1] % 该命令产生足够长的虚拟文本段落,需要使用 lipsum 宏包
picinpar
能够自动计算图表内容的大小,在环境中文本段落指定的位置开窗口放置此图表。不过,picinpar
也有一个缺点,即它要求环境中的段落在页面上必须有足够的空白,如果段落文字恰好在一页的末尾,就会在页面上留下大片的空白,这与使用 float
提供的不浮动的图表环境(H
选项)是一样的。此外,picinpar
在图表外面加的间距很小,不方便调整,figwindow
与 tabwindow
环境的语法也与一般的 LaTeX 环境不同。当图形大小或环境中文本内容在页面中位置不合适时,picinpar
偶尔还会造成错误的段落形状,需要在使用中小心调整。
3.6.2 wrapfig
宏包
wrapfig
宏包提供了 wrapfigure
和 wraptable
环境,在语法格式上更接近标准的 figure
和 table
环境:
% 中括号参数是可选的
begin{wrapfigure}[<行数>]{<位置>}[<外伸长度>]{<宽度>}
<图内容>
end{wrapfigure}
begin{wraptable}[<行数>]{<位置>}[<外伸长度>]{<宽度>}
<表内容>
end{wraptable}
在使用时,<图内容>
及 <表内容>
与普通 figure
、table
环境的内容相同,可以是任意代码产生的图表,也可以使用 caption
命令生成标题。在环境后面的段落内容江辉沿图表绕排。在这里,<位置>
参数不区分大小写,可以是 l,r
,即左右两侧;也可以用 o,i
,表示双页页面的装订内侧和外侧。<宽度>
则指定图表环境所占用的宽度。可选的 <行数>
可以指定图表占用的行数,如果留空则会按照内容高度自动计算(不过自动计算的结果有时偏大)。<外伸长度>
如果大于 000 pt,则图表会向左右侧面伸出版心指定的长度,产生特殊的效果。
% 导言区
usepackage{wrapfig}
% ……
begin{wraptable}[4]{r}[1.5cm]{4.5cm}
centering
caption{向右伸出的绕排表格}label{tag:wraptable}
begin{tabular}{|c|c|c|c|}
hline
甲 & 乙 & 丙 & 丁 \
hline
end{tabular}
end{wraptable}
wrapfig
在使用时可以不必指定把多少文字包含进绕排的范围,但它同样也有与 picinpar
类似的问题,即本页中剩下的空间必须足够放下被绕排的图表,否则也将造成难看的分页。在功能上,wrapfig
可以让图伸出版心之外,不过不能把图表放在中间或跳过前几行,因而与 picinpar
有互补的效果。
3.6.3 floatflt
宏包
floatflt
宏包与 wrapfig
类似,它提供了 floatingfigure
和 floatingtable
的浮动环境,可以把浮动体放在一段开头的左侧或右侧。floatflt
的独特功能是提供了 fltitem
命令,试图解决与列表环境共用时产生的问题。
3.6.4 shapepar
宏包
shapepar
宏包的 cutout
命令部分实现了复杂形状绕排功能,其基本语法格式为:
cutout{<side>}(<h_offset>,<v_offset>)<settings> shapepar <文字内容>
其中,必选的 <side>
参数只能为 l,r
。图表的默认的位置为盒子的中心位置,可选的 <h_offset>
、<v_offset>
分别表示图表由默认位置上在水平、垂直方向上的偏移,正值分别表示往右、下偏移,负值分别表示往左、上。
shapepar
宏包提供了许多预定义的绕排形状,详细参见官方文档:
texdoc shapepar
3.6.5 cutwin
宏包
cutwin
宏包也提供了类似 picinpar
、wrapfig
的绕排功能,同时与 shapepar
一样还支持自定义挖洞的形状。虽然没有 shaperpar
一样丰富的预定义形状,不过在处理绕排时其语法相对自然。cutwin
与 shapepar
宏包有命名冲突,具体用法参见官方文档:
texdoc cutwin