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 代码试试这个。试试看会发生什么:
- 有无
-dPDFFitPage
- 宽度和高度比原来小,比原来大
要查看应该如何工作,请尝试使用任何其他工具将示例图像转换为 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").
我正在尝试为 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 代码试试这个。试试看会发生什么:
- 有无
-dPDFFitPage
- 宽度和高度比原来小,比原来大
要查看应该如何工作,请尝试使用任何其他工具将示例图像转换为 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").