为什么我的 PDF 文件这么大?(以及如何真正解决它)
PDF 是一个容器,而不是单一格式——它的体积几乎完全来自内部嵌入的内容。这里讲清楚 PDF 臃肿的真正原因,以及什么方法真正有用。
· 阅读需 1 分钟
PDF 是一个容器,容器本身其实很小
"为什么这个 PDF 这么大"背后的困惑,通常源于把 PDF 当成像纯文本文件那样单一、统一的格式——但 PDF 更接近一种容器格式,在精神上和 ZIP 压缩包有点像,它把几种真正不同类型的内容打包在一起:页面排版指令、嵌入字体、嵌入图像、矢量图形和元数据,每一种都用自己的内部表示方式存储。容器结构本身——真正属于 PDF 特有的那部分——是很小的;一个只包含纯文本和简单排版、没有嵌入图像或特殊字体的 PDF,无论有多少页,通常只有几十 KB。每当一个 PDF 膨胀到几十甚至几百 MB 时,体积几乎总是来自容器内部嵌入的内容,而不是容器格式本身——这正是为什么"为什么我的 PDF 这么大"几乎总有一个具体、可识别的答案,而不是格式本身固有的属性。
目前最常见的原因:以印刷分辨率保存的扫描页面
通过扫描纸质页面生成的文档,从文件格式的层面看,其实根本不是文本文档——它是一系列整页照片,每页一张,包装在 PDF 容器里,照片文件体积的所有规律都适用于这里。扫描仪通常默认以 300 dpi 或更高分辨率捕获,这是为物理印刷复制校准的分辨率,对于只会在屏幕上查看的文档来说,这远远超出了实际需要的像素数据量。一份十页的扫描文档以印刷分辨率捕获,体积轻易就能达到几十 MB,原因正在于此:它不是十页文字,而是十张全分辨率照片,而这种分辨率的照片本身体积就大,不管它实际承载的视觉信息有多少。
这也是为什么扫描版 PDF 对压缩的反应会比真正基于文本的 PDF 明显得多:以更低但仍适合屏幕显示的分辨率、更激进但依然适度的压缩级别重新编码每一页图像,能在几乎不影响屏幕可读性的前提下,把扫描文档缩小 70% 到 90%,因为原始文件本来就携带了远超屏幕实际能用到的像素数据。
嵌入字体,以及它为何比大多数人预想的更重要
需要在任何设备上都渲染一致的 PDF,通常会把实际使用的字体文件直接嵌入到文档内部,而不是仅仅通过名称引用某种字体、寄希望于查看者的系统里恰好装有匹配的字体——对于可靠、一致的渲染来说,这确实是正确的工程选择,但它要付出真实的体积代价。一个嵌入的字体家族,尤其是包含多种字重和样式的,很容易给一个原本几乎全是文字的文档增加几百 KB。对于使用中文、日文或韩文文本的文档,这种影响会大得多:这些文字体系需要成千上万个不同的字形,而不是拉丁字母字体所需的大约一百个字符,所以一个完整嵌入的 CJK 字体本身就能达到几十 MB——往往是一个原本内容平平的文档里体积最大的单一组成部分。
构建良好的 PDF 生成工具会通过只嵌入文档实际使用的字形子集,而不是整个字体文件来处理这个问题,这样体积开销就与文本量成正比。一份用这种方式嵌入完整、未经子集化的大字符集字体文件的 PDF,其字体数据量可能远远超过页面上文字实际需要的量。
遗留的编辑历史与冗余的内部结构
一些 PDF 编辑工作流,特别是采用"增量保存"模式的——每次编辑都被追加到文件末尾,而不是重写整个文档——可能会在文件内部技术上依然保留早期版本的已编辑内容,即使这些内容已经不再可见——相当于编辑历史悄悄堆积在文档内部,而没有被清理掉。经过这种方式多轮编辑的 PDF,其携带的数据量可能明显超过它当前可见内容所暗示的量,因为其中一部分存储的内容已经不再展示给任何人。通过一个能根据文档当前可见状态重建文件的流程重新保存文档,而不是继续追加到现有结构上,就能清除这些内容。
什么方法真正有效,什么方法没用
以适合文档实际查看方式的分辨率和压缩级别重新编码嵌入的图像,是影响最大的修复方式,而且它之所以特别有效,是因为它针对的正是绝大多数超大 PDF 臃肿的真正原因——图像数据的捕获或嵌入保真度远超最终用途所需。重建文档的内部结构,清理增量编辑遗留的内容,是次一级但确实真实有效的方式。没什么用的做法,是对已经保存好的 PDF 再套用一层通用文件压缩工具:PDF 查看器和生成器内部已经使用标准、成熟的压缩方式压缩了大部分嵌入内容,所以在整个文件外面再包一层无关的通用压缩,通常只能省下百分之一二——明显少于重新处理实际的嵌入图像和结构所能省下的量,因为已经压缩过的文件里,几乎没有多少冗余留给第二次、不相关的压缩过程去发现了。