Ghostscript调整PDF大小不与ImageMagick PDF工作



我正在尝试为Linux编写一个小程序来调整pdf大小和调整页边距。我的计划是使用Ghostscript作为后端。这个终端命令成功地调整了大多数pdf文件的大小:

gs -q -sDEVICE=pdfwrite -dBATCH -dNOPAUSE -dFIXEDMEDIA -dPDFFitPage 
 -dDEVICEWIDTHPOINTS=300 -dDEVICEHEIGHTPOINTS=400 -sOutputFile=out.pdf file.pdf

-dPDFFitPage选项缩放页面以适应新的尺寸,如果图像长宽比与指定的尺寸不匹配,则添加空白作为填充。删除-dPDFFitPage将改变页面大小而不缩放-如果页面太大将被裁剪,或者如果太小将添加空白。

然而,该命令不适用于由ImageMagick的"convert"程序创建的pdf文件。PDF是缩放的,但没有添加空白,因此输出文件中只有一个维度是正确的。如果没有-dPDFFitPage选项,超大图像会按预期裁剪,但如果图像小于新页面大小(即没有添加空白),则不会发生任何事情。

问题似乎在于PDF除了图片外是空的。我怎么能让Ghostscript调整页面大小,并在必要时用白色填充页面的空白部分?

编辑:示例文件

要查看问题,请尝试使用这些示例文件(也有示例Ghostscript输出pdf)。或者,使用ImageMagick (或任何图像编辑器)自己创建一个合适的示例图像:

convert -size 500x500 xc:skyblue -fill black -draw "circle 250,250 0,250" image.png
现在,使用ImageMagick (NOT任何其他程序)将其转换为PDF:
convert image.png file.pdf

现在用Ghostscript代码试试这个。看看当您尝试它时会发生什么:

  • 含和不含-dPDFFitPage
  • 宽度和高度比原来的小,而它们更大
要查看假定如何工作,请尝试使用任何其他工具将示例图像转换为PDF。你可以(例如)使用LibreOffice或LaTeX,或者把你刚刚制作的PDF (不工作的那个)和"打印"它来创建另一个PDF (由于某种原因可以工作)。确保图像填充PDF的整个页面(在PDF中不应该有空白/边框,但由Ghostscript创建的输出PDF应该有一些空白)

您的原始PDF文件(NotWorking.pdf)除了/MediaBox之外还包含/CropBox。这被传递到输出的PDF文件,并且由于-dPDFFitPage的工作方式,它被以与PDF文件的实际内容相同的方式适当地修改。结果是缩放后的文件看起来与原始文件相同。

不一样,原文件的/MediaBox[0 0 500 500],修改后的文件的/MediaBox[0 0 300 400]。但效果是,在执行/CropBox的阅读器中,看起来与相同。

试着通过Ghostscript运行这两个"修改过的"文件,看看会发生什么。默认情况下,Ghostscript使用/MediaBox,而不是/CropBox

一旦您尝试通过Ghostscript运行两个输出文件,请尝试使用-dUseCropBox

你需要…

  • …或者禁用/CropBox
  • …或者将其设置为与/MediaBox
  • 相同

如果需要做pdfmark操作。

只是一个额外的指针…

  • 在输入PDF文件中已经有/CropBox定义的情况下,方法通过Ghostscript-c "[...pdfmark"参数提供一个将不起作用!

在这些情况下,它通常有助于首先"解除"现有的/CropBox关键字在PDF文件中改变为小写:使其读取/cropBox(因为PDF关键字是区分大小写的,它将不再被识别/使用)。

你可以用任何方法来做到这一点:文本编辑器(使用一个不会改变你背后的EOL字符!),或sed,或…

要检查,如果有定义的* box 不同于默认的/MediaBox(必须在每个PDF文件中),您可以使用pdfinfo -box。该命令将总是报告/MediaBox的值,而且还报告/CropBox/BleedBox/ArtBox/TrimBox的值。在PDF文档中没有明确定义/CropBox/BleedBox/ArtBox/TrimBox的情况下,工具将报告与/MediaBox设置相同的值:

$ pdfinfo -box "out(NotWorking).pdf"
 Title:          NotWorking
 Producer:       GPL Ghostscript 9.15
 CreationDate:   Sun May 24 00:38:55 2015
 ModDate:        Sun May 24 00:38:55 2015
 Tagged:         no
 UserProperties: no
 Suspects:       no
 Form:           none
 JavaScript:     no
 Pages:          1
 Encrypted:      no
 Page size:      300 x 300 pts
 Page rot:       0
 MediaBox:           0.00     0.00   300.00   400.00
 CropBox:            0.00    50.00   300.00   350.00
 BleedBox:           0.00    50.00   300.00   350.00
 TrimBox:            0.00    50.00   300.00   350.00
 ArtBox:             0.00    50.00   300.00   350.00
 File size:      16316 bytes
 Optimized:      no
 PDF version:    1.5

但是,在/CropBox定义显式存在,但设置为与/MediaBox设置相同的值的情况下,这没有帮助:

$ pdfinfo -box NotWorking.pdf
 Title:          NotWorking
 Producer:       ImageMagick 6.8.9-9 Q16 x86_64 2015-01-06 http://www.imagemagick.org
 CreationDate:   Sun May 24 00:21:28 2015
 ModDate:        Sun May 24 00:21:28 2015
 Tagged:         no
 UserProperties: no
 Suspects:       no
 Form:           none
 JavaScript:     no
 Pages:          1
 Encrypted:      no
 Page size:      500 x 500 pts
 Page rot:       0
 MediaBox:           0.00     0.00   500.00   500.00
 CropBox:            0.00     0.00   500.00   500.00
 BleedBox:           0.00     0.00   500.00   500.00
 TrimBox:            0.00     0.00   500.00   500.00
 ArtBox:             0.00     0.00   500.00   500.00
 File size:      12343 bytes
 Optimized:      no
 PDF version:    1.4

在这种情况下,您必须查看PDF源代码,或者运行:

for i in *.pdf ; do
   echo $i;
   echo -n "  ";
   grep -a -o --color -P "/.*?Box.*?]" "$i" ;
   echo ;
done
NotWorking.pdf
  /MediaBox [0 0 500 500]
  /CropBox [0 0 500 500]
Working.pdf
  /MediaBox [ 0 0 500 500 ]
out(NotWorking).pdf
  /Type/Page/MediaBox [0 0 300 400]
  /CropBox [0 50.0 300.0 350.0]
out(Working).pdf
  /Type/Page/MediaBox [0 0 300 400]

正如您所看到的,文件NotWorking.pdf确实已经预先设置了自己的显式/CropBox值…

还有一个警告:

上面给出的grep命令将不会发现/CropBox设置,如果相应的PDF对象被嵌入到/ObjStm对象("对象流")中而变得模糊。

最新更新