ghostscript 或 python:如何将不同页面大小的 pdf 组合成相同页面大小的 pdf?

Posted

技术标签:

【中文标题】ghostscript 或 python:如何将不同页面大小的 pdf 组合成相同页面大小的 pdf?【英文标题】:ghostscript or python : how to combine pdf of different page sizes into a pdf of same page sizes? 【发布时间】:2017-03-27 20:43:25 【问题描述】:

我在 *** 中搜索了问题。最近的链接是:How to set custom page size with GhostscriptHow to convert multiple, different-sized PostScript files to a single PDF?

但这不能解决我的问题。

这个问题很简单。 我们如何将多个 pdf(具有不同页面大小)组合成一个具有相同大小的所有页面的组合 pdf。

示例: 两个输入 pdf 文件是: hw1.pdf,单页大小为 5.43x3.26 英寸(从 adobe 阅读器中找到) hw6.pdf,单页大小为 5.43x6.51 英寸

可以在此处找到 pdf:https://github.com/bhishanpdl/Questions

代码是:

gs -sDEVICE=pdfwrite -r720 -g2347x3909 -dPDFFitPage -o homeworks.pdf hw1.pdf hw6.pdf

问题:第一个 pdf 是纵向的,第二个页面是横向的。问题:我们怎样才能让两个页面都是纵向的?

注意: -r720 是像素/英寸。 使用python脚本找到大小-g2347x3909:

wd = int(np.floor(720 * 5.43))
ht = int(np.floor(720 * 3.26))    

gsize = '-g' + str(ht) + 'x' + str(wd) + ' '
# this gives:  gsize = -g4308x6066

另一次尝试

commands = 'gs -o homeworks.pdf -sDEVICE=pdfwrite -dDEVICEWIDTHPOINTS=674 ' +\
               ' -dDEVICEHEIGHTPOINTS=912 -dPDFFitPage ' +\
               'hw1.pdf hw6.pdf'
subprocess.call(commands, shell=1)

这首先给出了两个页面的纵向,但它们的大小不同。 当我在 adobe reader 中打开输出时,第一页较小,第二页已满。 一般来说,我们怎样才能使所有页面的大小相同?

【问题讨论】:

【参考方案1】:

其中一个页面被旋转的原因(在第一个示例中)是因为它更适合这种方式。由于 Ghostscript 主要用作打印软件,因此假设您想要打印输入。如果输出是固定的媒体大小,则请求页面调整,并且请求的媒体大小在旋转时更适合(即缩放较少),那么内容将被旋转。

为了防止这种情况发生,您需要重写 FitPage 过程,该过程在过程 pdf_PDF2PS_matrix 的 /ghostpdl/Resource/Init/pdf_main.ps 中定义。您可以修改该过程,使其不会旋转页面以更好地适应。

在第二种情况下,您尚未设置 -dFIXEDMEDIA-g 表示 -dFIXEDMEDIA-dDEVICE...POINTS 没有),因此 PDF 文件中的媒体大小请求将覆盖您在命令中设置的媒体大小线。这就是为什么不调整页面大小的原因。由于媒体是 PDF 文件请求的大小,因此页面无需修改即可适应,因此-dPDFFitPage 将不执行任何操作。因此,如果您使用 -dDEVICE...POINTS任何 FitPage 开关,则需要设置 -dFIXEDMEDIA

建议您(作为您的第二次尝试)使用-dDEVICEWIDTHPOINTS-dDEVICEHEIGHTPOINTS 来设置媒体大小,因为它们不依赖于分辨率(与-g 不同),后者可以被 PostScript 输入覆盖程式。你不应该无故干涉决议,所以不要设置-r720

请注意,此过程不会“合并”、“合并”或任何其他暗示输入内容在输出中未更改的内容。在尝试使用此过程之前,您应该阅读有关该主题的documentation 并了解该过程。

【讨论】:

悲催,总结就是不能简单的做,需要彻底了解ghostscript后修改源代码?除了 GHOSTSCRIPT 是否还有其他工具,例如pdftk 之类的,我可以轻松地做这件事吗? 您可以修改 PostScript 程序,它并不完全是源代码(它有点像,因为 PostScript 是一种解释性语言,但它不需要更改基于 C 的 PostScript 解释器)。我确实指出了您必须在哪里进行更改,这并不是特别难,但它不会“开箱即用”。要求软件推荐是违反网站政策的,我不知道有什么可以做到这一点。这毕竟是开发者网站,修改代码吧。 感谢@KenS 的严谨回答,我有点期待一些简单的方法来做到这一点,它似乎比我想象的要复杂!【参考方案2】:

您已将此问题标记为“ghostscript”,但我假设您使用 subprocess.call() 并不反对使用 Python。

pdfrw Python 库的 pagemerge 画布可以做到这一点。在示例目录和 pagemerge.py 的源代码中有一些处理不同大小页面的示例。 fancy_watermark.py 显示了在应用水印的上下文中处理不同页面大小的示例。

pdfrw 可以在输出上旋转、缩放或简单地定位源页面。如果要旋转或缩放,可以查看示例目录。 (因为这是家庭作业,为了获得额外的学分,您可以通过查看各种页面大小来控制缩放和旋转。:) 但是如果您只想将第二页扩展到与第一页一样长,您可以这样做用这段代码:

from pdfrw import PdfReader, PdfWriter, PageMerge

pages = PdfReader('hw1.pdf').pages + PdfReader('hw6.pdf').pages
output = PdfWriter()

rects = [[float(num) for num in page.MediaBox] for page in pages] 
height = max(x[3] - x[1] for x in rects)
width = max(x[2] - x[0] for x in rects)

mbox = [0, 0, width, height]

for page in pages:
    newpage = PageMerge()
    newpage.mbox = mbox              # Set boundaries of output page
    newpage.add(page)                # Add one old page to new page
    image = newpage[0]               # Get image of old page (first item)
    image.x = (width - image.w) / 2  # Center old page left/right
    image.y = (height - image.h)     # Move old page to top of output page
    output.addpage(newpage.render())

output.write('homeworks.pdf')

(免责声明:我是 pdfrw 的主要作者。)

【讨论】:

以上是关于ghostscript 或 python:如何将不同页面大小的 pdf 组合成相同页面大小的 pdf?的主要内容,如果未能解决你的问题,请参考以下文章

没有得到任何输出或错误ghostscript python

如何在 Windows 中将 ghostscript DLL 库提供给 python?

python - 如何从子进程中运行的ghostscript命令中捕获错误

如何在 Python 中更改 Ghostscript 输出文件(在打印机后台处理程序中)

Ghostscript - 如何在 Windows10 或 Windows Server 2012 上抑制打印对话框

如何使用 ghostscript 将 PDF 转换为 PDF/A 或 PDF/X?