一句话
一个很重的 PDF,几乎全部体积都在图片里。一页打字的文本是 20–50 KB;一页 300 dpi 彩色扫描是 1–3 MB。压缩 PDF 的意思就是把这些图片按更低的分辨率或质量重新编码——文件里其它东西都不值得去缩。如果文档主要是文字却仍然太大,那是它的生成方式出了问题,解决办法是另一回事。
字节在哪
打开一个 PDF 的结构,里面是三类内容:
- 文字和矢量图形:以紧凑的指令存放(“在这里画这个字形”),已经用和 ZIP 一样的算法压过。一本 100 页的小说不到 1 MB。这里没什么可省。
- 字体:嵌进去,文件到哪都长一样。一套完整的中日韩字体 5–15 MB,但 PDF 生成器通常只嵌用到的字形(“子集化”),压到几十 KB。一个因为字体而重的 PDF,是导出时关掉了子集化——重新导出,不是压缩。
- 图片:照片、扫描件、logo,以及最常见的罪魁——扫描的一页,不管页上有什么,都是一整张图。
一份用手机扫的 12 页租房合同,就是 12 张 300–400 万像素的 JPEG。25 MB 就是这么来的,上传表单卡住的也是它。
“压缩 PDF”做的是什么
PDF 压缩器做一件有用的事:找到每张图片,解码,再以更小的方式编码——更低的 JPEG 质量、更低的分辨率,或两者都要。文字层、链接、书签原样不动。三个设置要紧:
- 分辨率。 300 dpi 的扫描是 OCR 和打印需要的。在屏幕上看,150 dpi 看起来一模一样,像素只有四分之一。一份只会在屏幕上看的表单可以到 100–120 dpi。分辨率减半,图片体积变四分之一;这是最大的杠杆,没有之一。
- JPEG 质量。 从 95 到 75 大约省 60%,文档上几乎看不出变化。低于 60,文字边缘开始糊。
- 颜色。 一份黑白表单的扫描件存成 RGB,是用三个通道装一个通道的内容。转灰度省三分之一;干净的文字页转成真正的黑白(1 位,CCITT 或 JBIG2 编码)能省 90%。
PDF 压缩在浏览器里做这件事——文档在你的机器上用 PDF.js 解码,每张图重新编码,再用 pdf-lib 重建文件——下载之前就显示结果大小。如果结果反而比原件大,它保留原件:这说明图片本来就小,压缩不是这份文件的答案。
压缩到不了的时候
- 限制很小而文档很长。 40 页扫描件不可能以可读的质量塞进 2 MB。把它拆分成表单真正要的那几页;多数“上传合同”的字段要的是签字页,不是附件。
- 已经压过了。 压缩器跑两遍除了让图片再糊一点什么都不会发生。工具报告只省了几个百分点,就停。
- 重在字体或内嵌文件。 有些 PDF 带附件、3D 模型或完整字体。从源文档(Word、Google 文档、设计软件)用“标准”或“最小体积”设置重新导出。
- 本该是文字的扫描件。 一封打字的信打印出来再扫描,比原信重一百倍。有原件就重新导出;只有扫描件的话,OCR 不会减小体积——图片留着,文字加在上面。
按这个顺序试
- 先看里面是什么:扫描件,就准备压缩;打字稿,就准备重新导出。
- 150 dpi、质量 75 压一次。光这一步就解决多数“25 MB → 5 MB 以内”的情况。
- 还大:转灰度,再到 120 dpi。
- 还大:拆分——只发要求的那几页。
- 最后手段:PDF 转图片用适中的分辨率导出,再图片转 PDF。这把一切压平成每页一张 JPEG,像素数完全由你控制;文字层没了,所以只对没人需要搜索或复制的文档这么做。
之后检查两样东西
打开结果,放大最小的文字——签名、脚注、印章上的字。过度压缩最先在那里露馅。另外,如果这个 PDF 带证书数字签名,任何重编码都会让签名失效,收件人会看到“签名后被修改”。这类文件,拆分是唯一安全的减重方式,而且连拆分也会破坏签名——发原件,去谈那个限制。