在Linux上使用Ghostscript减小PDF文件大小不起作用

时间:2012-08-07 17:05:59

标签: pdf size resolution ghostscript image-resizing

我有大约50-60个pdf文件(图像),每个文件大1.5MB。现在我不想在我的论文中有如此大的pdf文件,因为这会使下载,阅读和打印成为后方的痛苦。所以我尝试使用ghostscript执行以下操作:

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

然而,现在我的1.4MB pdf是1.5MB大。

我做错了什么?有什么办法可以检查pdf文件的分辨率吗?我只需要300dpi图像,所以有人会建议使用convert来改变分辨率,或者我可以用gs改变图像分辨率(减少它),因为我使用时图像非常粗糙convert

我如何使用转换:

 convert \
     -units PixelsPerInch \
      ~/Desktop/L_2lambda_max_1wl_E0_1_zg.pdf \
     -density 600 \
      ~/Desktop/output.pdf

示例文件

http://dl.dropbox.com/u/13223318/L_2lambda_max_1wl_E0_1_zg.pdf

2 个答案:

答案 0 :(得分:16)

如果您运行Ghostscript -dPDFSETTINGS=/screen,这只是一种捷径。实际上,您将(隐式地)获得一大堆使用的设置,您可以使用以下命令进行查询:

gs \
  -dNODISPLAY \
  -c ".distillersettings {exch ==only ( ) print ===} forall quit" \
| grep '/screen'

在我的Ghostscript(v9.06prerelease)上,我得到以下输出(稍加编辑以提高可读性):

/screen 
  << /DoThumbnails false 
     /MonoImageResolution 300 
     /ColorImageDownsampleType /Average 
     /PreserveEPSInfo false 
     /ColorConversionStrategy /sRGB 
     /GrayImageDownsampleType /Average 
     /EmbedAllFonts true 
     /CannotEmbedFontPolicy /Warning 
     /PreserveOPIComments false 
     /GrayImageResolution 72 
     /GrayACSImageDict << 
                        /ColorTransform 1 
                        /QFactor 0.76 
                        /Blend 1 
                        /HSamples [2 1 1 2] 
                        /VSamples [2 1 1 2] 
                      >> 
     /ColorImageResolution 72 
     /PreserveOverprintSettings false 
     /CreateJobTicket false 
     /AutoRotatePages /PageByPage 
     /MonoImageDownsampleType /Average 
     /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 << 
                          /ColorTransform 1 
                          /QFactor 0.76 
                          /Blend 1 
                          /HSamples [2 1 1 2] 
                          /VSamples [2 1 1 2] >> 
     /CompatibilityLevel 1.3 
     /UCRandBGInfo /Remove 
>>

我想知道你的PDF是否是图像密集的,如果这种转换不受欢迎(使用'错误'参数重新采样图像)会增加文件大小......

如果是这种情况(图像密集的PDF),请告诉我们,我会用一些建议更新这个答案....


更新

我查看了DNA提供的示例文件。有趣...

不,包含任何图片

相反,它包含一个大流(使用/FlateDecode压缩),其中包含大约700.000+(!!)个操作,主要是PDF语言中的单个矢量操作,例如:
  m(moveto),
  l(lineto),
  d(setdash),
  w(setlinewidth),
  S(中风),
  s(近距离和中风),
  W*(eoclip),
  rgRG(setrgbcolor)
  还有一些。

(那段PDF代码写得非常低效AFAICS(但确实有它的工作),因为它连接许多短笔画而不是做'长'笔画,而且几乎每个笔画都会再次定义颜色(即使它是与之前相同),并具有所有其他开销(开始笔划,结束笔划,......)。

Ghostscript的-dPDFSETTINGS=/screen此处没有任何效果(例如,没有图像可以下采样)。增加的文件大小(准确地说是+48 kByte)可能是由于Ghostscript在解释文件时将一些内部描边等命令重新组织为不同的顺序。

因此,您无法对PDF文件大小 ...

做多少
  • ...除非您将每个PDF页面转换为 REAL 图像,例如PNG:
    gs \
      -o out72.png \
      -sDEVICE=pngalpha \
       L_2lambda_max_1wl_E0_1_zg.pdf

(我使用pngalpha输出来获得透明背景。)'out.png'的图像尺寸为259x213px,文件大小现在为70 kByte。但我相信你不会喜欢它的质量: - )

输出质量“不好”,因为Ghostscript使用72 dpi的默认分辨率。

既然你说你想拥有300dpi,命令就变成了这个:

gs \
  -o out300.png \
  -sDEVICE=pngalpha \
  -r300 \
   L_2lambda_max_1wl_E0_1_zg.pdf

文件大小现在是750 kByte,图像尺寸是1080x889像素。


更新2

由于 Curiosity 现在很流行...... :-) ...我试图在Mac上使用Adobe Acrobat X Pro帮助降低文件大小。

你想知道结果吗?

执行'另存为...(缩小文件大小的PDF)' - 这对我来说过去总能产生非常好的效果! - 创建了一个1,8 ++ MByte文件(+ 29%)。我想这肯定会将Ghostscript的性能(文件大小增加+ 3%)变为现实的视角!

答案 1 :(得分:2)

DNA决定采用灰度PNG。他创建它们的方式分为两步:

  1. 第1步:使用Ghostscript的pdfwrite设备和设置,将彩色PDF页面(例如this)转换为灰度PDF页面 -dColorConversionStrategy=/Gray
    -dProcessColorModel=/DeviceGray
  2. 第2步:使用Ghostscript的pngalpha设备将灰度PDF页面转换为PNG,分辨率为300 dpi(GS命令行上为-r300)。
  3. 这会将他的初始文件大小减少到1.4 MB到0.7 MB。

    但是这个工作流程有以下缺点:

    • 与直接来自PDF的以相同分辨率写入的颜色输出相比,它丢失了所有颜色信息,而不会节省太多磁盘空间!

    DNA的工作流程有两种选择:

    1. (彩色)PDF的一步转换 - &gt; (颜色)PNG,使用Ghostscript的pngalpha设备,原始PDF作为输入(300 dpi分辨率的相同设置)。这将具有以下优势:

      • 它会将颜色信息保存在PNG输出中,只需要更多的磁盘空间!
    2. (彩色)PDF的一步转换 - &gt;灰度PNG,使用Ghostscript的pnggray设备,原始PDF作为输入(300 dpi分辨率的相同设置),具有这种优势/劣势的组合:

      • 会丢失PNG输出中的颜色信息。
      • 它会破坏DNA工作流程中保留的透明背景。
      • 它可以节省批次的磁盘空间,因为文件大小将降低到DNA工作流程输出的大约20%。
    3. 因此,您可以下定决心,并排查看输出大小和质量,这是一个用于演示差异的shell脚本:

      #!/bin/bash
      #
      # Copywrite (c) 2012 <kurt.pfeifle@gmail.com>
      # License: Creative Commons (CC BY-SA 3.0) 
      
      function echo_do() {
              echo
              echo "Command:     ${*}"
              echo "--------"
              echo
              "${@}"
      }
      
      [ -d out ] || mkdir out
      
      echo 
      echo "    We assume all PDF pages are 1-page PDFs!"
      echo "    (otherwise we'd have to include something like '%03d'"
      echo "    into the output filenames in order to get paged output)"
      echo
      
      echo '
       # Convert Color PDF to Grayscale PDF.
       # If PDF has transparent background (most do), 
       # this will remain transparent in output.)
       # ATTENTION: since we don't use a resolution,
       # pdfwrite will use its default value of '-r720'.
       # (However, this setting will only affect raster objects...)
      '
      for i in *.pdf
      do
      echo_do gs \
       -o "out/${i}---pdfwrite-devicegray-gs.pdf" \
       -sDEVICE=pdfwrite \
       -dColorConversionStrategy=/Gray \
       -dProcessColorModel=/DeviceGray \
       -dCompatibilityLevel=1.4 \
        "${i}"
      done
      
      echo '
       # Convert (previously generated) grayscale PDF to PNG using Alpha channel
       # (Alpha channel can make backgrounds transparent)
      '
      for i in out/*pdfwrite-devicegray*.pdf
      do
      echo_do gs \
       -o "out/$(basename "${i}")---pngalpha-from-pdfwrite-devicegray-gs.png" \
       -sDEVICE=pngalpha \
       -r300 \
        "${i}"
      done
      
      echo '
       # Convert (color) PDF to grayscale PNG using Alpha channel 
       # (Alpha channel can make backgrounds transparent)
      '
      for i in *.pdf
      do
      # Following only required for 'pdfwrite' output device, not for 'pngalpha'!
      #                -dProcessColorModel=/DeviceGray 
      echo_do gs \
       -o "out/${i}---pngalphagray_gs.png" \
       -sDEVICE=pngalpha \
       -dColorConversionStrategy=/Gray \
       -r300 \
        "${i}"
      done
      
      echo '
       # Convert (color) PDF to (color) PNG using Alpha channel
       # (Alpha channel can make backgrounds transparent)
      '
      for i in *.pdf
      do
      echo_do gs \
       -o "out/${i}---pngalphacolor_gs.png" \
       -sDEVICE=pngalpha \
       -r300 \
        "${i}"
      done
      
      echo '
       # Convert (color) PDF to grayscale PNG 
       # (no Alpha channel here, therefor [mostly] white backgrounds)
      '
      for i in *.pdf
      do
      echo_do gs \
       -o "out/${i}---pnggray_gs.png" \
       -sDEVICE=pnggray  \
       -r300 \
        "${i}"
      done
      
      echo " All output to be found in ./out/ ..."
      echo
      

      运行此脚本并并排比较不同的输出。

      是的,'直接灰度-PNG-from-color-PDF-using-pnggray-device'可能看起来 bit 更糟(并且它不具有透明背景)另一个 - 但它也只是其文件大小的20%。另一方面,如果你想通过牺牲一点磁盘空间来购买更多质量 - 你可以使用-r400而不是-r300 ......