优化 PDF 文件(使用 Ghostscript 或其他)

Posted

技术标签:

【中文标题】优化 PDF 文件(使用 Ghostscript 或其他)【英文标题】:Optimize PDF files (with Ghostscript or other) 【发布时间】:2012-05-14 01:47:00 【问题描述】:

如果您想优化 PDF 文件并减小文件大小,Ghostscript 是最佳选择吗?

我需要存储大量的 PDF 文件,因此我需要尽可能优化和减小文件大小

有人对 Ghostscript 和/或其他有任何经验吗?

命令行

exec('gs -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dCompatibilityLevel=1.4
-dPDFSETTINGS=/screen -sOutputFile='.$file_new.' '.$file);

【问题讨论】:

您是在寻找免费软件还是只寻找免费软件?还是专有的付费软件也是一种选择? 您知道 PDF 中哪些对象占用的空间最多吗?字体?高分辨率图像? 另见 pdfsizeopt 工具 (GPLv2) askubuntu.com/a/1011292/19753 【参考方案1】:

如果您正在寻找免费(如“libre”)软件,Ghostscript 无疑是您的最佳选择。然而,它并不总是很容易使用——它的一些(非常强大的)处理选项不容易找到文档。

看看这个答案,它解释了如何对图像分辨率下采样执行比通用-dPDFSETTINGS=/screen 所做的更详细的控制(它定义了一些您可能想要覆盖的整体默认值):

How to downsample images within pdf file?

基本上,它告诉您如何让 Ghostscript 将所有图像下采样到 72dpi 的分辨率(这个值是 -dPDFSETTINGS=/screen 使用的——您可能想要更低):

-dDownsampleColorImages=true \
-dDownsampleGrayImages=true \
-dDownsampleMonoImages=true \
-dColorImageResolution=72 \
-dGrayImageResolution=72 \
-dMonoImageResolution=72 \

如果您想尝试 Ghostscript 是否也能够“取消嵌入”所使用的字体(有时可以,有时不能 - 取决于嵌入字体的复杂性以及 on the font type used),您可以尝试将以下内容添加到您的 gs 命令中:

gs \
  -o output.pdf \
   [...other options...] \
  -dEmbedAllFonts=false \
  -dSubsetFonts=true \
  -dConvertCMYKImagesToRGB=true \
  -dCompressFonts=true \
  -c ".setpdfwrite <</AlwaysEmbed [ ]>> setdistillerparams" \
  -c ".setpdfwrite <</NeverEmbed [/Courier /Courier-Bold /Courier-Oblique /Courier-BoldOblique /Helvetica /Helvetica-Bold /Helvetica-Oblique /Helvetica-BoldOblique /Times-Roman /Times-Bold /Times-Italic /Times-BoldItalic /Symbol /ZapfDingbats /Arial]>> setdistillerparams" \
  -f input.pdf

注意:请注意,降低图像分辨率肯定会降低质量(不可逆地),并且去嵌入字体会使显示和打印 PDF 变得困难或不可能,除非安装了相同的字体机器……


更新

我在原始答案中忽略的一个选项是添加

-dDetectDuplicateImages=true

到命令行。此参数会导致 Ghostscript 尝试检测多次嵌入 PDF 中的任何图像。如果您将图像用作徽标或页面背景,并且 PDF 生成软件未针对这种情况进行优化,则可能会发生这种情况。旧版本的 OpenOffice/LibreOffice 曾经是这种情况(我测试了 LibreOffice 的最新版本 v4.3.5.2,它不再做这种愚蠢的事情了)。

如果您在pdftk 的帮助下连接 PDF 文件,也会发生这种情况。为了向您展示效果以及如何发现它,让我们看一个示例 PDF 文件:

pdfinfo p1.pdf

 Producer:       libtiff / tiff2pdf - 20120922
 CreationDate:   Tue Jan  6 19:36:34 2015
 ModDate:        Tue Jan  6 19:36:34 2015
 Tagged:         no
 UserProperties: no
 Suspects:       no
 Form:           none
 javascript:     no
 Pages:          1
 Encrypted:      no
 Page size:      595 x 842 pts (A4)
 Page rot:       0
 File size:      20983 bytes
 Optimized:      no
 PDF version:    1.1

Poppler 的 pdfimages 实用程序的最新版本增加了对 -list 参数的支持,该参数可以列出 PDF 文件中包含的所有图像:

pdfimages -list p1.pdf

 page num  type width height color comp bpc  enc interp objectID x-ppi y-ppi size ratio
 --------------------------------------------------------------------------------------
    1   0 image    423   600   rgb    3   8 jpeg     no     7  0    52    52 19.2K 2.6%

此示例 PDF 是一个 1 页文档,其中包含一个图像,该图像使用 JPEG 压缩进行压缩,宽度为 423 像素,高度为 600 像素,并以 52 PPI 的分辨率在页面上呈现。

如果我们像这样在pdftk 的帮助下连接此文件的 3 个副本:

pdftk p1.pdf p1.pdf p1.pdf cat output p3.pdf

然后结果通过pdfimages -list显示这些图像属性:

pdfimages -list p3.pdf

 page num  type width height color comp bpc  enc interp objectID x-ppi y-ppi size ratio
 --------------------------------------------------------------------------------------
    1   0 image   423    600   rgb    3   8 jpeg     no     4  0    52    52 19.2K 2.6%
    2   1 image   423    600   rgb    3   8 jpeg     no     8  0    52    52 19.2K 2.6%
    3   2 image   423    600   rgb    3   8 jpeg     no    12  0    52    52 19.2K 2.6%

这表明现在有 3 个相同的 PDF 对象(ID 为 4、8 和 12)嵌入在 p3.pdf 中。 p3.pdf 由 3 页组成:

pdfinfo p3.pdf | grep Pages:

 Pages:          3

通过用参考替换重复的图像来优化 PDF

现在我们可以借助 Ghostscript 应用上述优化

 gs -o p3-optim.pdf -sDEVICE=pdfwrite -dDetectDuplicateImages=true p3.pdf

检查:

 pdfimages -list p3-optim.pdf

 page num  type width height color comp bpc  enc interp objectID x-ppi y-ppi size ratio
 --------------------------------------------------------------------------------------
    1   0 image   423    600   rgb    3   8 jpeg     no    10  0    52    52 19.2K 2.6%
    2   1 image   423    600   rgb    3   8 jpeg     no    10  0    52    52 19.2K 2.6%
    3   2 image   423    600   rgb    3   8 jpeg     no    10  0    52    52 19.2K 2.6%

每页仍然列出一个图像 -- 但 PDF 对象 ID 现在始终相同:10。

 ls -ltrh p1.pdf p3.pdf p3-optim.pdf

   -rw-r--r--@ 1 kp  staff    20K Jan  6 19:36 p1.pdf
   -rw-r--r--  1 kp  staff    60K Jan  6 19:37 p3.pdf
   -rw-r--r--  1 kp  staff    16K Jan  6 19:40 p3-optim.pdf

如您所见,使用 pdftk 进行的“哑”连接将原始文件大小增加到原始文件大小的三倍。 Ghostscript 的优化使其大幅下降。

最新版本的 Ghostscript 甚至可以默认应用 -dDetectDuplicateImages(AFAIR,v9.02,首次引入,默认没有使用。)

【讨论】:

感谢您的回答 :) 已对其进行了测试,但是当您手动将 dpi 设置为 72 时,当设置 /screen 并且文件大小仍然较低@ 987654349@ :) 我的意思是.. /screen 的质量更好,而且文件大小比手动将 dpi 设置为 72 更小 @clarkk:我有兴趣查看显示这种情况的示例 PDF。你能提供一个(或者这是否侵犯了某人的隐私)? 这里 dynaccount.com/tmp/35.pdf 和这里 dynaccount.com/tmp/36.pdf.. 查看文档顶部的徽标.. 35.pdf (44.81kb - 手动 dpi) 和 36.pdf (44.73kb - /屏幕) 为了完整起见,这里提供了可用于使用 GhostScript/ps2pdf 转换 PDF 的选项列表:ghostscript.com/doc/current/Ps2pdf.htm【参考方案2】:

您可以通过将 PDF 转换为 Postscript,然后使用返回 PDF 来获得良好的结果

pdf2ps file.pdf file.ps
ps2pdf -dPDFSETTINGS=/ebook file.ps file-optimized.pdf

参数-dPDFSETTINGS 的值定义了生成的PDF 中图像的质量。选项从低质量到高质量:/screen/default/ebook/printer/prepress,请参阅 http://milan.kupcevic.net/ghostscript-ps-pdf/ 以获取参考。

Postscript 文件可能会变得非常大,但结果是值得的。我从 60 MB PDF 变成了 140 MB Postscript 文件,但最终得到了 1.1 MB 优化的 PDF。

【讨论】:

如果能在 Windows 环境中获得一些帮助,那就太好了... 有什么原因会导致文件比仅使用 gs 和适当的设置更小?此外,这样做会导致 Postscript 缺少某些功能(例如 alpha 透明度、渐变、ICC 配置文件)而导致的一些问题。 我不知道,只是报告在我的情况下效果很好,希望其他人也能从中受益。随意发布更好的解决方案或帮助改进现有的解决方案。 第一步是不必要的。 ps2pdf 将接受 pdf 输入文件。 @frabjous 首先转换为 ps 对我来说有很大的不同。这是 ps2pdf 和 pdf2ps 的 9.26 版【参考方案3】:

我使用 Ghostscript 和以下来自 here 的选项。

gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen \
 -dNOPAUSE -dQUIET -dBATCH -sOutputFile=output.pdf input.pdf

【讨论】:

请注意,虽然这个通常可以正常工作,但它无法正常处理可填充的 PDF @AlexFlo 你会用什么命令来实现这个?因为这个,我现在被困住了。【参考方案4】:

您可能会发现pdftocairo(来自Poppler)可以制作更小的 PDF,但请注意它会去除一些功能(例如超链接)。

【讨论】:

谢谢,我发现 ps2pdf14 有时会更改输出,在这种情况下,pdftocairo 使 PDF 更小(500K 到 110K)但被裁剪,所以我在保存为 PDF 之前在 Inkscape 中添加了显式边距,然后通过pdftocairo然后通过pdfcrop(来自Teχ)将其缩小到90K。【参考方案5】:

这对我有用

将您的 PDF 转换为 PS(这会创建一个大文件

pdf2ps large.pdf very_large.ps

将新 PS 转换回 PDF

ps2pdf very_large.ps small.pdf

来源: https://pandemoniumillusion.wordpress.com/2008/05/07/compress-a-pdf-with-pdftk/

【讨论】:

【参考方案6】:

您会损失质量,但如果这不是问题,那么 ImageMagick 的 convert 可能会很有帮助:

convert original.pdf reduced.pdf

请注意,它并不总是有效:我曾经使用此命令将 126MB 文件转换为 14MB 文件,但另一次它使 350Ko 文件的大小增加了一倍。

无论如何都值得一试……

正如 cmets 中提到的,在基于矢量的 PDF 上应用此命令当然没有意义,它只会对光栅化图像有用。

有关相关选项,另请参阅this post。

【讨论】:

这仅对基于扫描图像的 PDF 文件有意义,否则 ImageMagick 会将基于矢量的 PDF 转换为光栅图像,并且生成的文件实际上可能比原始文件更大。 @yms :我想你对基于矢量的 PDF 的看法当然是对的,但我相信它对任何类型的光栅图像都有意义,其中扫描图像只是一小部分。在我的例子中,文档是由普通的数码照片制作的。 是的,当然,我的意思是扫描图像是最常见的 PDF 文件用例,其中只有光栅图像(可能还有一些来自 OCR 的透明文本)。我只是想添加该评论作为对任何想要使用您的解决方案的人的评论。【参考方案7】:

Ghostscript 附带ps2pdf14 实用程序,可用于优化 PDF 文件,但在某些情况下,“优化”文件的大小可能比原始文件大。

【讨论】:

ps2pdf14 input.pdf output.pdfgs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dNOPAUSE -dQUIET -dBATCH -sOutputFile=output.pdf input.pdf 相同。对于纯文本内容,ouput.pdf 是 input.file 大小的 25% pdfopt 产生了更大的输出 pdfopt 不再附带 ghostscript

以上是关于优化 PDF 文件(使用 Ghostscript 或其他)的主要内容,如果未能解决你的问题,请参考以下文章

奇怪的问题,ghostscript 和 pdf 文件

使用 ghostscript 创建 pdf 文件

如何使用 Ghostscript 和 Ghostscript .NET 通过嵌入 IIC 配置文件生成正确的 PDF/A

GhostScript 和 PDF/A?

Ghostscript 剪辑一个 pdf 文件

使用 Ghostscript 从单个 JPG 文件创建 PDF - PDF 中的图像放置问题