Optimized PDF

· 931 words · 2 minute read

无意中,看到生成出来的 pdf 文件的属性中有这么一段:

Optimized:  No

这好奇心和强迫症一下就升腾上来了。我呕心沥血写的 Xelatex 文本,仔仔细细地修复了 UnderfullOverfull 报警,为啥会有这么个碍眼的 No?

什么是 Optimized PDF? 🔗

TUG 邮件列表有人曾经也问了这个问题, 简单来说 Properties 里面显示的这个 Optimized 准确来说,应该是Linearized 的意思,或者叫 Web-optimized.

普通 PDF 文件的索引表(xref table, 包含 pdf 文件内各个对象的偏移地址) 是放在文件末尾的。这样浏览器打开 pdf 时,需要等文件下载完成才能显示出来。如果索引表放在文件开头,且 PDF 文件内的对象按偏移排序,就能实现提前显示文档内容。

如何变成 Optimized? 🔗

对 PDF 文件的对象做排序是个事后处理过程,所有的 TeX engine 都不会做这个事情。有很多工具可以用来做这个 post-processing.

$ qpdf --linearize input.pdf optimized.pdf

这么处理以后,pdf 文件的尺寸可能反而稍微变大。因此,可以启用压缩:

$ qpdf --linearize --object-streams=generate --optimize-images \
       --compress-streams=y --compression-level=9 --recompress-flate \
	   input.pdf optimized.pdf

Optimizing PDFs with Ghostscript 🔗

Ghostscript 官网的优化建议非常有信息含量。首先,“优化” 这个词对于不同的用户可能有不同的含义,可能是:

  • Fast web view: -dFastWebView;
  • Minimise file size: -dPDFSETTINGS=configuration
  • Conforming to a subset of the PDF specification (e.g., PDF/A -DPDFA)
  • Produce a PDF file without errors: -dPDFSTOPONERROR and -dPDFSTOPONWARNING

其中,-dPDFSETTINGSconfiguration 参数可以是:

  • /screen - 72 DPI, 面向低分辨率输出设备;
  • /ebook - 150 DPI, 面向中等分辨率输出设备;
  • /printer - 300 DPI, 类似 Acrobat Distiller “Prepress Optimized”.
  • /press - 300 DPI,类似 Acrobat Distiller “Print Optimized”.
  • /default - 默认设置。

上面每项设置具体影响的输出参数可以在官网文档找到。和之前使用 qpdf 做压缩不同的是,应用 -dPDFSETTINGS 可能会改变 PDF 的显示质量。比如,指定 /ebook 虽然可以使输出的 PDF 文件小很多,但字体的 DPI (Dots Per Inch) 和图片的分辨率都会受影响。因此,可以精细化指定 gs 参数,比如:

$ gs -sDEVICE=pdfwrite -dFastWebView -dPDFSETTINGS=/ebook \
     -dColorImageResolution=300 -dGrayImageResolution=300 \
	 -dNOPAUSE -dQUIET -dBATCH \
	 -sOutputFile=optimized.pdf input.pdf

上面的例子中,指定 /ebook 后又额外设置了图片的分辨率。这里有更多花式用法。

乱码问题 🔗

gs 处理了一番之后,PDF 元数据中的 TitleAuthor 中文信息变成了乱码。看起来,这是个BUG, 以及参考

贴子得知, PDF 文档 info dictionary 中的文本字段需要是 PDFDocEncoding 处理过, 或者 UTF-16BE with a Byte Order Mark (BOM). 一番操作后,发现了新世界:

  • 指定 pdfmarks, 其中包含带 UTF-16BE with BOM 编码的 Title 和 Author. 重新用 gs 处理后,用 evince 看,仍然是乱码;
  • Nautilus 文件浏览器看到的 pdf 属性里面,这两个元数据里的中文也是乱码;
  • 用 pdfinfo 输出元数据,发现中文显示正常,和没有指定编码后的 pdfmarks 时一样;
  • gs 处理后的 PDF 用 firefox 或者 SumatraPDF 查看元数据,中文并没有乱码。

究竟是 viewer 的问题,还是 model 的问题,还没有定论。T_T

comments powered by Disqus