资讯详情

资讯详情

LaTeX图片插入完全指南:从浮动体机制到排版实战

LaTeX排版经验总结这个系列我第一篇就想写图片插入。原因无他——几乎每个刚上手LaTeX的人都会在插图这一步碰一鼻子灰明明按教程写了\includegraphics编译却报File not found图片放得好好的一编译就跑到了下一页双栏模板里大图把版面撑得乱七八糟。这些问题我全踩过后来才慢慢明白LaTeX的图片插入本质上是一套浮动体管理逻辑和所见即所得编辑器里手动拖图完全是两种思路。这篇文章不准备讲高深技巧只把我写论文、写技术报告期间积累的图片插入经验从宏包配置、浮动位置、尺寸控制到编译链路和报错排查完整梳理一遍。适合刚开始用LaTeX写论文的同学也适合被图片排版折磨过但还没理清思路的朋友。1. 图片插入的地基宏包、环境与最小示例1.1 graphicx宏包图片插入的入口一上来先装宏包。LaTeX插图的几乎所有核心能力都来自graphicx\usepackage{graphicx}这个宏包提供了最常用的\includegraphics命令。不加它你连最基础的插图都做不了。早期还会有人让你根据编译引擎加[pdftex]或[dvipdfmx]这样的驱动选项以指定图片应该由哪个底层驱动处理但现在的主流发行版基本都能自动检测直接写\usepackage{graphicx}就够了无须手动指定驱动加了反而容易出现多余警告。graphicx真正厉害的地方在于它把图片文件的加载方式抽象成了参数化的形式。你可以通过可选的键值参数控制插入图片的宽度、高度、旋转角度、裁剪区域等等。建议把graphicx加入你的固定宏包清单凡是写文档先从它开始。这里说一下我的习惯文档里第一次使用某个宏包时最好把它的名字和用途在注释里记下来。我见过不止一位同学图插不出来时翻到导言区才发现自己压根没加载graphicx。这种问题最难排查因为报错信息往往不是你忘了宏包而是文件找不到这类间接提示。1.2 figure浮动环境图片不是放进去的初学者最常走的弯路是直接在正文中间写一行\includegraphics{xxx.png}然后奇怪图片为什么和文字挤在一起、编号没法自动管理。正确做法是把图片放进figure浮动环境中\begin{figure}[htbp] \centering \includegraphics[width0.8\textwidth]{figures/architecture.png} \caption{系统架构示意} \label{fig:architecture} \end{figure}这里每个元素都有讲究。figure环境本身是一个浮动体它允许LaTeX在排版时把图片挪到合适的位置比如页面顶部或者单独一页。这样做的目的是避免图片处留下的巨大空白把版面利用得更紧凑。\centering让图片在环境中居中显示。注意它不是\centerline也不是center环境后两者会产生额外垂直间距。\caption{...}负责生成图注图片的编号也是由它负责的。\label{fig:architecture}给这个图贴一个标签之后在正文里用\ref{fig:architecture}就能自动引用编号。写论文时你经常要写如图3所示用这个机制可以省掉手改编号的麻烦。有一个顺序问题要特别注意\label一定要放在\caption之后。如果放在\caption前面\ref引用到的往往是上一张图的编号或者干脆是当前章节的编号这是很多人遇到的引用编号不对问题的根源。1.3 一个能跑通的最小示例拿一段可以直接复制编译的示例来说明。\documentclass{article} \usepackage{graphicx} \begin{document} 本文的系统结构如图\ref{fig:arch}所示。 \begin{figure}[htbp] \centering \includegraphics[width0.8\textwidth]{figures/arch.png} \caption{系统结构图} \label{fig:arch} \end{figure} \end{document}把figures/arch.png这个文件放在文档所在目录下的figures子目录里用pdflatex编译就能得到带编号、带图注的插图效果。第一次跑这个示例时我建议你故意把路径写错一次亲眼看看报错长什么样以后再遇到就不会慌。比如把figures/arch.png写成arch.png编译时就会出现类似File arch.png not found的提示。这种故意制造错误的练习法比单纯抄代码更能帮你建立排查直觉。2. 浮动位置理解LaTeX的自动排版逻辑2.1 位置参数的真实含义图不按你的剧本来是LaTeX新手最大的痛点。你在[htbp]里写的字母分别代表hhere尽量放在当前位置ttop放在页面顶部bbottom放在页面底部pfloat page单独放在一个浮动页上。很多人以为写了[h]图片就必须原地出现。不是的。h在LaTeX内部是一个允许项一个尽量项而不是强制项。LaTeX会根据版面情况决定是否真的放在当前位置如果当前页剩余空间放不下或者浮动体队列里已经积累了太多对象LaTeX会自行调整。真正的强制位置是[H]来自float宏包用法\usepackage{float} \begin{figure}[H] \centering \includegraphics[width0.6\textwidth]{figures/example.png} \caption{强制定位示例} \label{fig:force} \end{figure}2.2 为什么[h]经常不生效这里值得多说一句背后的逻辑。LaTeX的浮动算法会维护一个浮动体队列图片不是一下子放到页面上的而是先进入队列再在合适的时机被冲到页面上。LaTeX会在页面的顶部、底部、文字中间寻找空位。为了防止版面失衡它有一组内部预设的阈值\topfraction页面顶部最多能放多少比例的浮动体\bottomfraction页面底部最多能放多少比例\textfraction页面上至少保留多少比例的正文文字\floatpagefraction浮动页至少填充多大比例才允许成立。我写论文时经常遇到一种情况文字写得比较满图片比例又比较大于是\textfraction要求当前页必须有足够的正文图就被整体推到了下一页。这不是bug是LaTeX在维护排版的美观性。打个比方它像一条运河里的航运调度每一张图都是一艘货船得等水流条件合适、水位够了才放行通过。如果你确实想放松限制可以手动调这几个宏例如\renewcommand{\topfraction}{0.9} \renewcommand{\bottomfraction}{0.8} \renewcommand{\textfraction}{0.1}这些数值的意思是允许页面顶部和底部容纳更大的浮动体、允许正文最少只占10%。调完之后图片被赶走的情况会明显减少。但我要提醒一句不要为了图必须在某处而把阈值改得过激进否则文章会变得像补丁摞补丁。我在早期的论文里就吃过这个亏为了把一张图固定在理想位置一顿操作把版面搞得乱七八糟最后投稿返工反而更浪费时间。排版这事局部有时需要为整体让路。2.3 [H]到底该不该用[H]强制定位的优点是可以按照代码顺序逐图排布很适合那些必须紧跟某段论述的图比如实验截图、算法流程图。缺点也很明显它会强制在当前位置插入如果剩下的页面空间不够会直接把图片推到下一页并在前一页留下一大块空白而且[H]对跨栏环境的figure*支持不好双栏模板中通栏图用了[H]经常出错或无法跨栏。我的习惯是正文短、图表少的小文档比如课程作业、技术备忘录大胆用[H]正式论文和报告尽量用[htbp]或[!htbp]让LaTeX自己掌控页面。!的作用是放宽内部启发式条件相当于告诉LaTeX别那么多顾虑尽量按我给的参数来。如果确实需要紧跟文字还有一个技巧把图片放在一个不会被打断的小节或段落后面并用[t]明确让它出现在页面顶部这样版面比[H]自然很多。3. 尺寸、子图与样式让图片真正融入版面3.1 用相对宽度控制图片大小控制插图大小是排版中最常做的操作。\includegraphics里三个最常用的参数是width图片显示宽度height图片显示高度scale按原始尺寸缩放的比例。我几乎不用scale因为原始图片的物理尺寸千差万别同样的scale0.5在不同图片上效果完全不同。推荐用width配合相对单位最常用的写法是\includegraphics[width0.8\linewidth]{figures/arch.png}\linewidth是指当前行的可用宽度。在单栏文档里它约等于文字区域的宽度在双栏文档里它等于当前栏的宽度。也就是说用\linewidth做基准图片无论放在单栏还是双栏都会自动适配所属栏的宽度不会超宽。这里顺便区分几个容易混淆的概念\textwidth整个页面的文字区域宽度单栏文档中它就是版心宽度\columnwidth当前栏的宽度双栏排版时它是\textwidth的一半\linewidth当前行实际可用的宽度在列表、引文等环境中可能比\columnwidth还窄。在figure环境里用0.8\linewidth是稳妥的。如果某张图特别高就用height0.5\textwidth这种写法让它高度控制在半页左右。想保持原始宽高比时加上keepaspectratiotrueLaTeX会在width和height两个约束下尽量等比例缩放避免图片被压扁或者拉长。3.2 并排图与子图论文中最常用的组合写论文时左边一张原图右边一张处理结果是非常常见的排版需求。最简单的并排方式是用minipage\begin{figure}[htbp] \centering \begin{minipage}{0.48\linewidth} \centering \includegraphics[width\linewidth]{figures/input.png} \caption{原始输入} \label{fig:input} \end{minipage}\hfill \begin{minipage}{0.48\linewidth} \centering \includegraphics[width\linewidth]{figures/output.png} \caption{处理结果} \label{fig:output} \end{minipage} \end{figure}注意两个细节每个minipage的宽度最好都在0.5\linewidth以下两个加在一起约等于0.96\linewidth中间用\hfill做弹性空隙这样无论纸张多宽两张图都能均匀分布。minipage里的\includegraphics[width\linewidth]表示图片撑满所在的迷你页面而不是整个页面的宽度。如果你需要给子图分别编号比如生成(a)(b)两个子图再用一个大编号那就用subcaption宏包\usepackage{subcaption} \begin{figure}[htbp] \centering \begin{subfigure}{0.45\linewidth} \centering \includegraphics[width\linewidth]{figures/input.png} \caption{输入图像} \label{fig:sub-input} \end{subfigure}\hfill \begin{subfigure}{0.45\linewidth} \centering \includegraphics[width\linewidth]{figures/output.png} \caption{输出图像} \label{fig:sub-output} \end{subfigure} \caption{某算法的输入与输出} \label{fig:main} \end{figure}这样正文里可以引用\ref{fig:main}得到总编号也可以引用\ref{fig:sub-input}得到类似3a的子图编号。我在实验章节经常用这种结构把同一个数据集的多组结果放成两行四列的矩阵配合\subcaption非常直观。3.3 旋转、裁剪和花式操作偶尔会遇到图片方向不对或者四周有大量空白需要裁掉的情况。旋转用angle参数\includegraphics[width0.5\linewidth, angle90]{figures/photo.jpg}裁剪用trim加clip\includegraphics[trim10mm 5mm 15mm 8mm, clip, width0.6\linewidth]{figures/screenshot.png}trim后依次是左、下、右、上四个边的裁剪量单位可用mm、cm、pt等。注意只写trim不会真正裁掉图片只是把可视区域缩小必须同时加上clip关键字才会以裁剪后的边界作为实际排版边界。我在处理截图时经常用到这个功能把截图四周无意义的边框裁掉版面会干净很多。还有一个容易踩的坑如果同时指定width和height而没有keepaspectratio图片会被拉伸变形。有些模板会要求插图的宽度统一但原图高矮不一这时候我通常先设置统一的width让高度自然变化而不是强行统一height。4. 路径、格式与编译链路插图背后的隐形工程4.1 路径策略把图片组织成可维护的结构图片路径问题是File not found类报错的最大来源。我的建议从一开始就养成规范在文档根目录下建一个figures文件夹所有图片放进去在导言区用\graphicspath声明\graphicspath{{figures/}{figures/subdir/}}这里的语法很容易写错。\graphicspath接收的是一组用花括号包裹的路径每个路径的末尾必须带正斜杠/整体最外层还要再套一层花括号。比如\graphicspath{{figures/}}外层花括号是参数列表内层花括号是第一个路径。如果写成\graphicspath{figures/}多半会报错或者干脆不生效。路径里的分隔符一定要用/即使Windows系统默认用\在LaTeX里也要改成/。另外文件扩展名可以写也可以不写——\includegraphics{figures/arch}和\includegraphics{figures/arch.png}都能工作LaTeX会按编译引擎支持的格式自动尝试。但不写扩展名有个好处如果你同一目录下既有arch.pdf又有arch.pngLaTeX会优先选择适合当前编译引擎的格式这在后期切换编译方式时非常舒服。4.2 图片格式选型矢量图优先位图看分辨率LaTeX对图片格式的支持与编译引擎强相关。使用pdflatex编译直接支持PDF、PNG、JPG不支持EPS使用latex生成DVI编译传统上是EPS的天下使用xelatex编译主流格式都能处理但内部对EPS的兼容方式也比较微妙最稳妥还是用PDF。所以现在的主流工作流里图片格式基本就三类程序生成的示意图、流程图、矢量图一律导出成PDF清晰度无损缩放不变形照片、截图、位图素材用PNG或JPG老旧的EPS素材要么用工具转成PDF要么加载epstopdf宏包让编译过程自动转换。关于位图分辨率我的经验是普通打印看的话300dpi基本够如果图片要放很大比如整页宽建议原始分辨率更高一些。一张1280x720的截图如果拉宽到16cm算下来只有不到200dpi印刷会发虚。LaTeX不会帮你提升分辨率它只会忠实地按原始像素放大。所以准备插图时宁可原图大一点也不要后期用插值放大。4.3 编译引擎与图片支持的联动很多初学者搞不清pdflatex、xelatex、lualatex的区别。简单说pdflatex是LaTeX最经典的PDF编译路径速度快但中文字体支持麻烦xelatex更擅长处理中英文混排可以直接使用系统字体lualatex在字体和脚本方面更灵活。具体到图片插入你只需要记住无论用哪个引擎我都建议把图片准备成PDF/PNG/JPG如果模板要求latex编译才需要专门考虑EPS。我在写中文学位论文时通常用xelatex配合模板自带的宏包。图片插入的写法没有任何区别照常\includegraphics即可。如果用pdflatex遇到过EPS报错可以临时在导言区加\usepackage{epstopdf}很多情况下能自动把EPS转成PDF插入省去手工转换。还有一个小提示在一些在线LaTeX编辑平台上默认用pdfLaTeX编译左侧菜单可以切换XeLaTeX。如果本地编译正常、在线上却报图片相关错误优先检查两边的编译引擎是否一致。这个坑我踩过一次本地用xelatex跑得好好的在线默认引擎跑出来全是图片格式错误切换后就正常了。5. 常见问题与排查技巧实录5.1 高频报错速查表报错信息常见原因解决思路File xxx not found路径错误、文件名拼写错误、大小写不一致、图形文件不在搜索路径检查\graphicspath检查文件名大小写把图片放到文档同级目录先排除路径问题Unknown graphics extension: .epspdflatex下直接插EPS转成PDF或加载epstopdf宏包或换xelatexNot in outer par mode在另一个浮动体或minipage等受限上下文中使用了figure调整结构把浮动体移到外层合适位置Division by 0图片尺寸信息异常、高度或宽度参数为0、图片文件损坏打开图片文件确认能否正常显示去掉异常的尺寸参数图片显示空白框使用了draft模式图片未真正嵌入去掉draft或改用final确认图片文件存在Overfull \hbox图片或内容超出页面宽度把width改成0.x\linewidth不要用原图绝对宽度这张表是我自己排查时反复用到的。遇到报错先看是哪一类再按表格里的思路定位基本能解决绝大部分问题。代码里的报错信息通常还会包含行号根据行号跳到对应位置重点检查\includegraphics和figure环境附近有没有写错。5.2 图片不显示但编译无报错先怀疑draft模式有一种特别迷惑的情况编译没有任何报错但PDF里的图片位置只有一个空白或者一个带文件名的框。这多半是graphicx以draft模式加载了\usepackage[draft]{graphicx}draft模式会让LaTeX不真正嵌入图片只画一个和图片尺寸相同的黑框并在框里写出文件名。这样做的好处是编译速度快适合草稿阶段反复改文字时使用。到了最终输出时改成final即可。另外正文里也可以局部用\setkeys{Gin}{draftfalse}恢复不过一般没必要。我自己的习惯是在文章结构还没定稿时开着draft几天之内写草稿编译速度能快不少定稿前统一切换成final再检查一遍所有图片确实都正常显示了。如果你看到别人给的模板里加载graphicx时带draft记得在提交版本里删掉或改成final否则审稿人看到的就是一堆空框。5.3 版面微调间距、跨栏与文字环绕第一类图注与图片之间的间距。默认间距通常没什么问题但如果你的模板要求图注与图之间空0.5行可以用\vspace{0.5\baselineskip}手动调节。要注意\vspace放在\caption前后效果不同图注在下方时调整的是图和注之间的空隙。第二类双栏排版中的跨栏大图。双栏模板用figure放单栏图用figure*放通栏图。如果通栏图一直跑不到理想位置多半是因为双栏浮动体的约束更多我通常放[t]让它出现在页面上方配合\dbltopfraction等参数放宽限制。这里不推荐用[H]处理figure*很多模板会报错或产生奇怪的空白。第三类文字环绕图片。需要wrapfig宏包\usepackage{wrapfig} \begin{wrapfigure}{r}{0.4\textwidth} \centering \includegraphics[width0.35\textwidth]{figures/example.png} \caption{文字环绕示例} \label{fig:wrap} \end{wrapfigure}{r}表示图片在右侧{l}表示左侧。用wrapfigure有个经验它必须放在段落开头附近如果插图前已经写了一整段文字它可能报not in outer par mode或排版错乱。我一般会在需要环绕的位置另起一段把wrapfigure放在段落第一行之前。5.4 一点经验之谈图片插入之所以劝退很多人不是因为命令难记而是因为LaTeX的浮动体理念和所见即所得工具完全不同。一旦接受了让LaTeX决定放置位置、我们只负责提供内容和构图约束这个设定大部分问题都会迎刃而解。我自己现在的固定流程是先建好figures目录图片统一命名导言区配好graphicx和\graphicspath写正文时只负责把图放进figure环境并给出width编译后用\ref检查引用编号最后再针对个别版面问题微调位置参数。一个让我少走很多弯路的习惯每插入一张图就立刻编译一次。图片问题往往有连带效应——一张图路径错了可能导致整个浮动体系列错乱到最后一堆报错混在一起根本无从下手。循序渐进编译定位问题永远是第一位的。最后分享一个小技巧如果你在写一篇长论文里面有几十张图建议给每张图的文件名带上简短的含义前缀比如fig-arch-01.png、fig-arch-02.png而不是1.png、2.png。图片多了以后这种命名习惯能让你在\includegraphics和\label之间快速对应也能避免从别人那里继承来的项目里出现一堆含义不明的文件名。插图这件事说到底只有两条原则结构清晰、位置合理。做到了剩下的排版交给LaTeX就好。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →