我正在尝试为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文件(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
对象("对象流")中而变得模糊。