图像格式与插入

要在论文或书籍中放入照片、曲线图或示意图,需要把外部图像文件引入文档。入口就是 graphicx 包提供的 \includegraphics 命令。本页整理图像插入的基本语法,缩放、旋转、裁剪等选项,图像搜索路径的设置,以及最关键的:各个 TeX 引擎能读取哪些格式。贯穿全页的两个要点是:图像分为矢量图和栅格图两类;可接受的格式取决于所用的编译引擎。

graphicx 与 \includegraphics

图像插入由标准的 graphicx 包负责。在导言区用 \usepackage{graphicx} 加载它,然后在正文中写 \includegraphics[options]{filename}。graphicx 扩展了较早的 graphics 包;它的特点是可以用 key=value 形式集中指定选项。两者都随 LaTeX 标准的 latex-graphics 套件发布,因此不需要额外安装。

document.tex
\documentclass{article}
\usepackage{graphicx}
\begin{document}
\includegraphics[width=0.6\textwidth]{plot}
\end{document}

这里要记住的是:从文件名中省略扩展名。在上面的例子中,如果存在 plot.pdfplot.png,LaTeX 会根据引擎自动选择合适的格式。写死扩展名会让以后替换格式更麻烦;像 plot.tar.gz 这样文件名中含有句点时,也可能被误解析。出于同样原因,图像文件名最好避免空格和句点

如果图像放在其他文件夹中,可以用 \graphicspath 添加搜索路径。每个目录名都要单独放在花括号中(即使只有一个目录也要这样),并且末尾必须加正斜杠 /(Windows 上也用 /)。 LaTeX 会先查找当前目录,然后按顺序查找列出的目录。包含空格的路径要放在引号中,例如 {"my figures/"}

latex
\usepackage{graphicx}
\graphicspath{ {figures/} {../shared-figures/} }

尺寸、旋转与裁剪选项

\includegraphics 的方括号中按 key=value 形式列出选项。实际使用中几乎总要指定尺寸。width=height= 直接指定输出的宽度或高度;相对于 \textwidth(正文宽度)或 \linewidth 写成 width=0.8\textwidth,就能让图像按版面缩放。scale= 是相对于图像原始尺寸的倍率。

同时指定 width=height= 会破坏宽高比,使图像变形。keepaspectratio 可以避免这一点:设置后,图像会在给定宽度和高度的范围内保持比例缩放。要旋转图像,在 angle= 中给出按逆时针方向计量的角度(度)。例如 angle=90 会把图像旋转四分之一圈。

要裁掉图像边缘,可组合使用 trim=cliptrim 的四个值按 左、下、右、上 的顺序给出(注意不是直观的上下左右顺序)。默认单位是 bp(big point)。并且一定要加 clip:没有它时,本来要裁掉的部分不会被丢弃,而会溢出到周围正文中。负值则相反,会增加边距。还可以用 viewport= 以绝对坐标指定裁剪窗口。

latex
% 幅を本文幅の半分に
\includegraphics[width=0.5\textwidth]{photo}

% 縦横比を保って枠に収める
\includegraphics[width=8cm,height=5cm,keepaspectratio]{photo}

% 反時計回りに 90 度回転
\includegraphics[angle=90,width=6cm]{diagram}

% 左20 下20 右30 上10(bp) を切り落として表示
\includegraphics[trim=20 20 30 10,clip,width=6cm]{scan}

主要选项可以整理成表。实际使用时通常会组合多个选项。

选项作用
width=输出宽度;像 0.8\textwidth 这样的相对值很方便
height=输出高度
scale=相对于原始尺寸的倍率(scale=0.5 表示一半)
angle=逆时针旋转角度(度)
keepaspectratio同时给出宽度和高度时保持比例
trim= … clip裁掉左、下、右、上;需要 clip,默认单位为 bp
page=选择多页 PDF 中要插入的页

矢量图与栅格图

图像大致分为两类,选择哪一类会影响最终质量。矢量图用数学坐标描述点、线、曲线和文字,PDF、EPS、SVG 是典型例子。由于轮廓会根据数学描述重新计算,任意放大都保持清晰,文字也锐利。栅格图(位图)则是由带颜色的像素组成的网格,主要是 PNG 和 JPEG。放大时每个像素都会变大,边缘会变得锯齿状或模糊。

经验法则是:由线条和文字构成的图,例如曲线图、线稿、电路图、含公式的图,应使用矢量格式(PDF/EPS/SVG)。 它不依赖打印分辨率,在纸上和屏幕上都能保持最佳质量。照片、截图等连续色调图像应使用栅格格式(PNG/JPEG)。 把照片转成矢量图没有好处,只会让文件变大。使用栅格图时,请准备足以印刷的分辨率(通常 300 dpi 以上)的原始数据。如果在 LaTeX 内生成图形(如 TikZ、pgfplots 等),输出自然就是矢量图。

再说一下 PNG 与 JPEG 的取舍。JPEG 是面向照片的有损压缩,文件较小,但在线条和文字边缘会出现压缩噪声。PNG 是无损压缩,适合截图、平面色彩图形以及需要透明度的图像。拿不准时:照片用 JPEG,其余栅格图用 PNG。

各引擎可读取的格式

这里最容易出错。\includegraphics 接受哪些格式,取决于由哪个 TeX 引擎处理文件,以及最终由哪个驱动程序生成输出。现代主流的 pdfLaTeX、LuaLaTeX、XeLaTeX(直接输出 PDF 的路线)可以原生读取 PDF、PNG、JPEG。但是这些引擎不能直接读取 EPS。相反,传统的 latex + dvips 路线(经过 DVI)可以原生处理 EPS,但不适合 PDF 或 PNG。

日文中常用的 pLaTeX / upLaTeX 会输出 DVI,再用 dvipdfmx 转成 PDF。这一路线可以处理 PDF、PNG、JPEG、EPS。对于 PNG、JPEG、PDF,有时需要一个记录图像尺寸(边界框)的辅助文件(.xbb),可用 extractbb 工具生成。使用 pLaTeX/upLaTeX 配合 graphicx 时,最好像 \usepackage[dvipdfmx]{graphicx} 这样明确指定输出驱动程序(pdfLaTeX 等会自动判断)。

处理路线原生格式EPS?
pdfLaTeXPDF、PNG、JPEG不能直接读取;用 epstopdf 转换
LuaLaTeXPDF、PNG、JPEG不能直接读取;用 epstopdf 转换
XeLaTeXPDF、PNG、JPEG不能直接读取;用 epstopdf 转换
pLaTeX/upLaTeX + dvipdfmxPDF、PNG、JPEG、EPS可以(需要边界框)
latex + dvipsEPS(PostScript 系列)这是它的原生格式

实际结论很简单:新建文档时,图最好准备为 PDF、PNG 或 JPEG,这样无论 pdfLaTeX、LuaLaTeX、XeLaTeX 还是 dvipdfmx 都能直接处理。只有手头只有 EPS 或 SVG 时,才需要下面两节的转换。处理路线本身的细节,请参见“处理方式与流程”页面。

插入 EPS 与 SVG

EPS (Encapsulated PostScript) 是一种较早的矢量格式,某些期刊的旧投稿规定仍会要求它。要在 pdfLaTeX 等路线中使用 EPS,必须先转成 PDF;但如果加载 epstopdf package,EPS 文件会在编译时自动转换为 PDF 并直接插入。其机制是接入 graphicx 的处理流程,用 Ghostscript 转换;如果同名 PDF 已存在,就跳过转换。由于自动转换会运行外部程序,编译时要加 --shell-escape(或 -shell-escape。直接处理 EPS 时,文件开头表示图像范围的 BoundingBox 必须存在且正确。

latex
\usepackage{graphicx}
\usepackage{epstopdf}  % EPS をコンパイル時に PDF へ自動変換
% コンパイル例: pdflatex --shell-escape main.tex

SVG 是 Web 上的标准矢量格式,但 TeX 引擎不能直接读取。要插入 SVG,可使用 svg package。它提供 \includesvg{file},内部调用 Inkscape 的命令行功能,把 SVG 转换为 PDF(生成 DVI 输出时则转换为 EPS)。它还会把 SVG 内的文字导出到单独文件中,由 LaTeX 排版,因此标签能以文档自身字体清晰输出。由于需要调用 Inkscape,它同样要求 --shell-escape,并且需要可用的 Inkscape 安装。否则,先用 Inkscape 或其他工具把 SVG 转成 PDF 是更可靠的做法。

反向转换,也就是想从 TeX 输出生成 SVG 时,可以使用 dvisvgm。它能把 DVI(以及 EPS、PDF)转换为 SVG,支持 pTeX 的竖排 DVI 和 XeTeX 的 XDV,并把所需字体的字形轮廓嵌入 SVG。想把公式或图单独做成 SVG 放到 Web 上时很有用。

figure 浮动体与常见问题

\includegraphics 只是把图像放在当前位置;它不会添加编号,也不会添加 caption。论文中通常把图像放进 figure environment,作为带编号的“图”处理。这样 LaTeX 会根据页面布局把它浮动到合适位置,\caption{…} 会给出带编号的说明,\label/\ref 则允许在正文中写“参见图 3”这样的引用。

latex
\begin{figure}[htbp]
  \centering
  \includegraphics[width=0.7\textwidth]{plot}
  \caption{測定値と理論曲線の比較。}
  \label{fig:plot}
\end{figure}

図~\ref{fig:plot} に示すように……

浮动体的位置、[htbp] 的含义以及并排放置多幅图,见“浮动体与放置”页面;caption 样式和子图见“题注与子图”页面。这里先列出插入图像时常见的几个问题。

  • 引擎格式不匹配:把 EPS 交给 pdfLaTeX 等会因 “Cannot determine size of graphic” 之类的错误停止。请把图转换为 PDF/PNG/JPEG,或用 epstopdf 转换。
  • EPS BoundingBox:缺失或错误的 BoundingBox 行会导致位置不正确。可用 ps2epsepstool 修正。
  • 多页 PDF:默认只插入第一页。用 page= 选择页面(整份文档可用 pdfpages package)。
  • PDF 留白:图形 PDF 的边距过大会让图显得很小。先用 pdfcrop(CTAN)裁掉多余留白。
  • 文件名中的空格或句点:路径或名称中的空格、句点常会破坏插入。请改名,或给含空格的路径加引号。
  • 写死扩展名:指定扩展名会妨碍以后更换格式。一般只写不带扩展名的名称。