合并 PDF 的 Ghostscript 压缩结果
Posted
技术标签:
【中文标题】合并 PDF 的 Ghostscript 压缩结果【英文标题】:Ghostscript to merge PDFs compresses the result 【发布时间】:2011-12-30 19:26:26 【问题描述】:我发现这个巧妙的命令可以使用 Ghostscript 将多个 PDF 合并为一个:
gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=out.pdf in1.pdf in2.pdf
生成的大小小于 2 个 PDF 的总大小。
以单个文件作为输入运行命令仍会导致输出文件更小。
Ghostscript 上是否有一个选项,可以在合并时复制页面而不进行任何压缩?
如果不是,是不是因为 Ghostscript 的压缩效果好到完全没有质量损失?
【问题讨论】:
【参考方案1】:我在 ios 终端上成功使用了以下代码递归压缩多个 PDF。我发布它是因为我无法通过简单的复制和粘贴找到适合我的内容。
find . -name '*.pdf' | while read pdf; do gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook -dNOPAUSE -dQUIET -dBATCH -sOutputFile="$pdf_new.pdf" "$pdf"; done
请注意,您可能需要不同的输出质量,因此您可以更改 -dPDFSETTINGS
参数,如下所示:
-dPDFSETTINGS=/screen
:质量较低,尺寸较小。-dPDFSETTINGS=/ebook
:质量更好,但 pdf 文件稍大。-dPDFSETTINGS=/prepress
:输出类似于 Acrobat Distiller“印前优化”设置。-dPDFSETTINGS=/printer
:选择类似于 Acrobat Distiller“打印优化”设置的输出。-dPDFSETTINGS=/default
:选择旨在用于各种用途的输出,可能以牺牲更大的输出文件为代价。
【讨论】:
【参考方案2】:您观察到的一些尺寸优化可能来自 Ghostscript 对未使用对象的清理、最近获得的字体优化改进(您使用的是最新版本的 GS 吗?!?)以及可能的图像重新采样/下采样这可能已经发生了。
Ghostscript,如果用于PDF -> PDF 转换,基本上是这样操作的:
-
读入输入文件及其所有对象,并将它们转换为图形页面表示的内部格式。
对内部格式的页面内容进行在命令行上要求的操作。
编写一个全新的 PDF。
这意味着对于大多数 PDF -> PDF 操作,您将对 PDF 对象有不同的排序和编号,甚至对象的内部代码也可能已更改(即使您的眼睛没有发现输入和输出 PDF 之间的任何差异)。
默认情况下,Ghostscript 还会压缩原始文件中未压缩的任何对象流(但这是无损压缩)。
现在对于您非常简单的命令行不包含任何操作愿望,Ghostscript 假设您想使用-dPDFSETTINGS=/default
,隐式设置此参数并进行相应操作。
现在什么是/default
PDFSETTINGS?!您有两种选择:
阅读手册。大号table in middle of this section 给出了概述。您可以看到-dPDFSETTINGS=/default
本身只是它所代表的其他几十个更具体设置的简写。给定文档的链接是针对开发代码的当前 HEAD当然您实际使用的版本可能不同。
查询(您自己的)Ghostscript 以了解此设置的详细含义。 我对问题 'Querying Ghostscript for the default options/settings of an output device...' 和问题 'What are PostScript dictionaries, and how can they be accessed (via Ghostscript)?' 的回答对此进行了详细说明。简而言之,要查询 Ghostscript 以了解其 /default
PDFSETTINGS 的详细信息,请运行以下命令:
gs \
-q \
-dNODISPLAY \
-c ".distillersettings /default get exch ==only ( ) print === forall quit"
你应该得到一个非常相似的结果:
/Optimize false
/DoThumbnails false
/PreserveEPSInfo true
/ColorConversionStrategy /LeaveColorUnchanged
/DownsampleMonoImages false
/EmbedAllFonts true
/CannotEmbedFontPolicy /Warning
/PreserveOPIComments true
/GrayACSImageDict << /HSamples [2 1 1 2] /VSamples [2 1 1 2] /QFactor 0.9 /Blend 1 >>
/DownsampleColorImages false
/PreserveOverprintSettings true
/CreateJobTicket false
/AutoRotatePages /PageByPage
/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]
/ColorACSImageDict << /HSamples [2 1 1 2] /VSamples [2 1 1 2] /QFactor 0.9 /Blend 1 >>
/DownsampleGrayImages false
/UCRandBGInfo /Preserve
其中唯一突出的一点是:您可能希望将 /AutoRotagePages
从 /PageByPage
更改为 /None
。在命令行上,你可以把它写成-dAutoRotatePages=/None
。
为您提供一个完整的参数列表,这些参数将专门告诉 Ghostscript 通过添加这些参数来尽可能多地使用 passthrough 模式到输入 PDF:
-dAntiAliasColorImage=false \
-dAntiAliasGrayImage=false \
-dAntiAliasMonoImage=false \
-dAutoFilterColorImages=false \
-dAutoFilterGrayImages=false \
-dDownsampleColorImages=false \
-dDownsampleGrayImages=false \
-dDownsampleMonoImages=false \
-dColorConversionStrategy=/LeaveColorUnchanged \
-dConvertCMYKImagesToRGB=false \
-dConvertImagesToIndexed=false \
-dUCRandBGInfo=/Preserve \
-dPreserveHalftoneInfo=true \
-dPreserveOPIComments=true \
-dPreserveOverprintSettings=true \
所以你可以试试这个命令:
gs \
-o output.pdf \
-sDEVICE=pdfwrite \
-dAntiAliasColorImage=false \
-dAntiAliasGrayImage=false \
-dAntiAliasMonoImage=false \
-dAutoFilterColorImages=false \
-dAutoFilterGrayImages=false \
-dDownsampleColorImages=false \
-dDownsampleGrayImages=false \
-dDownsampleMonoImages=false \
-dColorConversionStrategy=/LeaveColorUnchanged \
-dConvertCMYKImagesToRGB=false \
-dConvertImagesToIndexed=false \
-dUCRandBGInfo=/Preserve \
-dPreserveHalftoneInfo=true \
-dPreserveOPIComments=true \
-dPreserveOverprintSettings=true \
input1.pdf \
input2.pdf
最后,正如 Chris Haas 已经暗示的那样:如果您特别不想要 Ghostscript 默认应用的任何优化,您也可以使用 pdftk
。 pdftk
根本无法做这样的事情,你会因为它相对笨拙的操作而获得相当多的速度(但也可能比从 Ghostscript 输出的文件大小要大得多)。
【讨论】:
pdftk
自 2016 年 3 月起不适用于 CentOS/RHEL 7。
您能否应用-dPDFSETTINGS=
设置之一,然后稍后在命令行中使用-d*
设置(在您的答案中)仅覆盖其中的一部分?
@CMCDragonkai:是的,你可以。 (不过我还没有测试过。但是如果这不起作用,那将是一个错误。)
这里有一个重新打包的 pdftk 版本,适用于 Centos 7 linuxglobal.com/pdftk-works-on-centos-7【参考方案3】:
这里有一些additional options 可以在使用pdfwrite
作为您的设备时传递。根据该页面,如果您没有通过任何东西,那么-dPDFSETTINGS
将设置为接近/screen
,尽管它没有变得更具体。您可以尝试将其设置为 -dPDFSETTINGS=/prepress
,它只能压缩 300 dpi 以上的内容。
gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile=out.pdf in1.pdf in2.pdf
另一种选择是pdftk:
pdftk in1.pdf in2.pdf cat output out.pdf
【讨论】:
感谢您推荐 pdftk。对于 PDF 文件的简单连接,它似乎是完美的。 FWIW:pdftk
不适用于 CentOS/RHEL 7。
我碰巧丢失了页面,并且gs
的大小增加了 10 倍。 pdftk
无需修改即可连接,而且速度更快。以上是关于合并 PDF 的 Ghostscript 压缩结果的主要内容,如果未能解决你的问题,请参考以下文章