Ghostscript 调整 PDF 大小不适用于 ImageMagick PDF

Ghostscript resize PDF not working with 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 调整页面大小并在必要时用白色填充页面的空白部分?

编辑:示例文件

要查看问题,请尝试使用这些 example files(也有示例 Ghostscript 输出 PDF)。

或者,使用 ImageMagick (或任何图像编辑器) 自己创建合适的示例图像:

convert -size 500x500 xc:skyblue -fill black -draw "circle 250,250 0,250" image.png

现在,使用 ImageMagick 不是 任何其他程序) 将其转换为 PDF:

convert image.png file.pdf

现在用 Ghostscript 代码试试这个。试试看会发生什么:

要查看应该如何工作,请尝试使用任何其他工具将示例图像转换为 PDF。您可以(例如)使用 LibreOffice 或 LaTeX,或者使用您刚刚制作的 PDF (那个不起作用) 和 "Print" 创建另一个 PDF (出于某种原因会起作用)。确保图像填满 PDF 的整个页面(您使用 Ghostscript 测试的 PDF 中不应有 whitespace/border,但 Ghostscript 创建的输出 PDF 应有一些空白。)

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

不一样,原始文件的 /MediaBox[0 0 500 500],修改后的文件的 /MediaBox[0 0 300 400]。但效果是它 看起来 相同,在 reader 中强制执行 /CropBox

通过 Ghostscript 尝试 运行 这两个 'modified' 文件,看看会发生什么。 Ghostscript 默认支持 /MediaBox,而不是 /CropBox

通过 Ghostscript 尝试 运行 两个输出文件后,请使用 -dUseCropBox 尝试。

你需要...

  • ...要么禁用 /CropBox
  • ...或将其设置为与 /MediaBox
  • 相同

如果需要做一个pdfmark操作。您可能想参考 this answer 以获得更多指示。

只是一个额外的指针...

  • 在输入 PDF 文件中已经有 /CropBox 定义的情况下,方法通过 -c "[...pdfmark" 参数为 Ghostscript 不行!

在这些情况下,首先 "disarm" PDF 文件中现有的 /CropBox 关键字通常会有所帮助,方法是将其更改为小写:使其显示为 /cropBox(因为 PDF 关键字是区分大小写,不再是 recognized/used).

您可以使用任何方法完成此操作:文本编辑器(使用不会在您背后更改 EOL 字符的编辑器!),或 sed,或...

要检查是否定义了与默认 /MediaBox 不同 的 *Boxes(每个 PDF 文件中必须存在),您可以使用 pdfinfo -box。此命令将 始终 报告值,不仅 /MediaBox,而且 /CropBox/BleedBox/ArtBox/TrimBox ].在 /CropBox/BleedBox/ArtBox/TrimBox 未在 PDF 文档中明确定义的情况下,该工具将报告与 /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 预设值...

还有一个警告,请注意:

My grep command given above will not discover the /CropBox setting in cases where the respective PDF object is obscured by being embedded into an /ObjStm object ("object stream").