【问题标题】:Ghostscript to merge PDFs compresses the result合并 PDF 的 Ghostscript 压缩结果
【发布时间】: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 的压缩效果好到完全没有质量损失?

【问题讨论】:

    标签: pdf 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 转换,基本上是这样操作的:

      1. 读入输入文件及其所有对象,并将它们转换为图形页面表示的内部格式。
      2. 对内部格式的页面内容进行在命令行上要求的操作
      3. 编写一个全新的 PDF。

      这意味着对于大多数 PDF -> PDF 操作,您将对 PDF 对象有不同的排序和编号,甚至对象的内部代码也可能已更改(即使您的眼睛没有发现输入和输出 PDF 之间的任何差异)。

      默认情况下,Ghostscript 还会压缩原始文件中未压缩的任何对象流(但这是无损压缩)。

      现在对于您非常简单的命令行不包含任何操作愿望,Ghostscript 假设您想使用-dPDFSETTINGS=/default,隐式设置此参数并进行相应操作。

      现在什么/default PDFSETTINGS?!您有两种选择:

      1. 阅读手册。大号table in middle of this section 给出了概述。您可以看到-dPDFSETTINGS=/default 本身只是它所代表的其他几十个更具体设置的简写。给定文档的链接是针对开发代码的当前 HEAD当然您实际使用的版本可能不同

      2. 查询(您自己的)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 默认应用的任何优化,您也可以使用 pdftkpdftk 根本无法做这样的事情,你会因为它相对笨拙的操作而获得相当多的速度(但也可能比从 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 无需修改即可连接,而且速度更快。
      猜你喜欢
      • 2019-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多