使用 Ghostscript 调整 PDF 大小
Posted
技术标签:
【中文标题】使用 Ghostscript 调整 PDF 大小【英文标题】:Resizing a PDF using Ghostscript 【发布时间】:2011-11-18 18:43:43 【问题描述】:我正在尝试将 PDF 缩放,例如仅 A4 大小的 PDF 到 A4。
这适用于纵向文档。文档已正确放大,然后将填充添加到顶部。
虽然没有添加横向文档填充。因此,文档最终将成为 A4 的正确高度,但不够宽,因为文档侧没有添加填充(如我所愿)。
这是我用来处理 A4 纵向文档的方法:
gs \
-sOutputFile=output.pdf \
-sDEVICE=pdfwrite \
-sPAPERSIZE=a4 \
-dCompatibilityLevel=1.4 \
-dNOPAUSE \
-dBATCH \
-dPDFFitPage \
input.pdf
【问题讨论】:
【参考方案1】:您的命令根本不进行任何缩放,它只是获取一个 PDF 文件并将其转换为 PDF 文件。
我建议您尝试添加 -dPDFFitPage 这将缩放 PDF 文件中的页面以匹配当前页面大小(在这种情况下由 -sPAPERSIZE 指定)。
这通常适用于具有已定义纸张大小的打印机,因此可能不适用于没有固定页面大小的 pdfwrite 设备,但值得一试。
【讨论】:
感谢您的回复,虽然我已经使用了 -dPDFFITPAGE 参数,但这并不能正常工作。 有一些方法(丑陋的)来缩放 PDF 输入,但通常不是必需的。你能分享一个示例文件来看看吗? 我尝试使用 -FIXEDMEDIA 开关,但没有帮助。最后,我不得不将 php 的每一页附加到 A4 空白文档中。这是我最终能得到的唯一解决方案【参考方案2】:您应该添加-dFIXEDMEDIA
开关:
gs \
-o output.pdf \
-sDEVICE=pdfwrite \
-sPAPERSIZE=a4 \
-dFIXEDMEDIA \
-dPDFFitPage \
-dCompatibilityLevel=1.4 \
input.pdf
如果您需要强制指定特定的纸张/页面/介质尺寸并忽略文档中指定的纸张/页面/介质尺寸,则始终需要-dFIXEDMEDIA
。因为 PDF 总是定义了纸张/页面/介质大小(PostScript 可能有,也可能没有......)。
(我的-o ...
更短,可以省去添加-dBATCH -dNOPAUSE
的时间——但仅适用于较新版本的 Ghostscript。)
【讨论】:
感谢 A5 和单行:gs -sDEVICE=pdfwrite -sPAPERSIZE=a5 -dFIXEDMEDIA -dPDFFitPage -dCompatibilityLevel=1.4 -o out.pdf in.pdf
谢谢,它有效!我用的是 A3:gs -o outputA3.pdf -sDEVICE=pdfwrite -sPAPERSIZE=a3 -dFIXEDMEDIA -dPDFFitPage -dCompatibilityLevel=1.4 input.pdf
如何防止这个命令出现的质量大幅下降?
无法访问您使用的 PDF,无法回答此问题。通常使用此命令不会“大幅降低质量”!它使用默认的 Ghostscript 设置,这些设置(几乎)等同于 '-dPDFSettings=/printer'
。更多详情,请查看 here 和 here 和 especially here .
Ghostscript 出于某种原因不断旋转我的页面。【参考方案3】:
遗憾的是 pstops 的功能,一个非常有用的软件包 缩放和合并后记页面,似乎不可用 对于 pdf。有一个名为 pdftopdf 的程序,但确实如此(据我所知 可以看到)做与 pstops 相同的事情。 您可以制作一个 ps 文件(我打印到 evince 中的文件),使用 pstops,然后 然后是 ps2pdf,但那很笨拙。
【讨论】:
【参考方案4】:似乎可以(最好)通过以磅为单位指定大小而不使用-dPDFFitPage来强制输出大小。我得到小数点大小,这很糟糕。以下是使用按需打印服务的 A5 打印。 “真实”A5 为 420x595 点。我发现使用 -sPAPERSIZE=a5 会给出小数点页面大小,但这可能是因为原始文件不可靠。
gs \
-o output.pdf \
-sDEVICE=pdfwrite \
-dDEVICEWIDTHPOINTS=419 -dDEVICEHEIGHTPOINTS=595 \
-dFIXEDMEDIA \
-dCompatibilityLevel=1.4 \
input.pdf
为了测试这一点,我发现使用 PDFshuffler 我能够导出单个页面,然后使用 pdfinfo 我能够获得这些页面的精确大小。这证实了明确使用设备参数有帮助。
【讨论】:
【参考方案5】:首先,感谢所有在这里发帖的人。
我有一个名为pdfScale 的小脚本,它吸收了此处发布的部分答案。所以我决定退回我的 2 美分。我使用了一些库尔特和蒂姆的答案。不过和蒂姆的更相似。我已经玩了几天了,这是我对此处发布的方法的部分结论:
使用-sPAPERSIZE
按名称设置纸张尺寸
以 PS 点为单位设置纸张大小-dDEVICEWIDTHPOINTS
、-dDEVICEHEIGHTPOINTS
-dDEVICEWIDTH
、-dDEVICEHEIGHT
,而不是更长的积分版本,但它们似乎都做同样的事情(都获得积分)。
因为我的 bash 脚本已经能够获取源页面大小,并且我喜欢能够设置自定义页面大小的想法,所以我决定专注于以磅为单位设置页面大小。我还已经在我的脚本中包含了GS Paper Sizes(带有名称和大小)。所以获取这些信息也很容易。
正如前面所指出的,在这两种情况下似乎都必须使用-dFIXEDMEDIA
。
这就是我的方法(以脚本方式)
-
获取源 PDF 页面大小(用于翻转检测)
以磅为单位获取目标的页面大小(例如 A4 > 595x842)
如有必要,检查它们是否具有相同的方向或翻转目标
使用点或翻转点运行 GS
当我试图解决自动旋转问题时,I found this other Kurt response。
这是关于使用-dAutoRotatePages
。只是在这里复制他的一部分答案:
-dAutoRotatePages=/None
-- 保留每个页面的方向;
-dAutoRotatePages=/All
-- 根据一种“多数决定”旋转所有页面(或不旋转);
-dAutoRotatePages=/PageByPage
-- 单独自动旋转页面。
我的脚本默认为PageByPage
,但这是可以调整的。它在我的测试中运行良好。使用-dAutoRotatePages
似乎也减少了预先翻转页面大小的需要,即使它不是一回事。我保留了这两个选项。
我的小应用程序最初是为了缩放 PDF(不更改页面大小)而创建的。然后我现在添加了做一个,另一个或两者的功能。不过,我仍然无法在一个 GS 调用中完成所有操作。
这就是我要求调整大小,将变量更改为实际值的原因。这是 A4 纵向尺寸,PageByPage
自动旋转:
gs \
-q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dSAFER \
-dCompatibilityLevel="1.5" -dPDFSETTINGS="/printer" \
-dColorConversionStrategy=/LeaveColorUnchanged \
-dSubsetFonts=true -dEmbedAllFonts=true \
-dDEVICEWIDTHPOINTS=595 -dDEVICEHEIGHTPOINTS=842 \
-dAutoRotatePages='/PageByPage' \
-dFIXEDMEDIA -dPDFFitPage \
-sOutputFile='../myOutputFile.pdf' \
-f '../input.pdf'
请注意,我也在使用 -dFIXEDMEDIA
和 -dPDFFitPage
。因为这适合页面,所以我的脚本的另一部分可能很方便在调整大小后缩放 PDF 中的内容(特别是如果 PDF 的比例发生了很大变化)。这就是我在脚本中调整大小后总是运行缩放的原因之一(在混合模式下)。
关于使用纸张名称时的分数问题,在将转换从毫米/英寸四舍五入到点之前,我遇到了这种情况。在我开始对它们进行四舍五入后,它们似乎总是需要的。不过,GS 会降低这些值似乎很奇怪。
所以我的结论是,困难的部分是找到一种解决方案,该解决方案适用于具有不同尺寸和方向的不同文档。我仍然不确定我使用的是正确的解决方案。但是通过让用户更改翻转检测和 GS 自动旋转,我希望至少在大多数情况下都有解决方案。
我还重建了这个过程中的大部分代码,现在很容易阅读。如果您想自己自动执行此类任务,检查它可能很有用。当然,仅缩放/调整 PDF 大小也很有用:
https://github.com/tavinus/pdfScale
PS:pdfScale 起源于on this *** thread。
【讨论】:
以上是关于使用 Ghostscript 调整 PDF 大小的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 GhostScript 设置 PDF 文件的输出图像大小限制
如何使用 ghostscript 调整 .eps 文件的大小