合并两个半页PDF文件与PHP


Merge Two Half-Page PDF Documents with PHP

我的一个朋友在一家报社工作,他周一问我这个问题,我不能确定这是否可能。

我知道可以使用PHP合并2个PDF(因为我已经看到许多其他问题已经回答),但我不确定的是,如果我可以合并半页PDF来填充另一个PDF的空间。

想象如下:我有PDF1:半页PDF,然后我有一个3页的PDF: Pdf2。在PDF2的第一页,我有一个空白的空间来容纳PDF1。

我可以这样做吗?如何?

我不能给你具体的源代码,但我可以解释如何在非常低的层次上做到这一点。而且,你所寻找的与出版业所谓的"植入"相似。

您开始的方式与合并相同,这意味着从另一个文档中拉入页面。您必须递归地引入页面的所有依赖项。但是要注意避免无限循环,PDF中确实存在无限循环,因此必须跟踪所访问的对象。不要使用递归函数,因为您的堆栈很容易溢出,PDF引用可能非常深。你应该在堆上实现遍历递归(深度优先搜索很好)。

在PDF上冲压PDF的关键是将源Page对象转换为XObject表单(不要与AcroForms或可填充表单字段混合使用)。XObject表单与Page对象非常相似,但有以下几种例外:

  • /Type /Page变为/Type /XObject /Subtype /Form
  • MediaBox页和CropBox页合为/BBox页。但是要小心,它们都可以通过页面树继承,所以你必须寻找继承属性。
  • 页面Rotate(也可继承)变成Matrix,这是一个变换(旋转)矩阵,而不是一个角度。
  • 页面的Resources, GroupMetadata可以不加更改地引入并添加到表单对象。
  • 必须将页面Contents流传输到表单。但是,页面Contents是一个外部对象,并且可能是一个数组,这意味着您需要合并这些片段。XObject是一个流对象。
  • 所有其他属性都很棘手,如果你不确定,你可能想忽略它们。

完成后,您所要做的就是在新页面上绘制XObject表单。您必须为XObject生成一个惟一的名称,并将其添加到页面的Resources中。绘画本身是一系列cmDo操作符,就像绘画图像一样。如果你需要裁剪原始内容,那么你还需要在Do之前设置一个剪切路径。

不用说,这远非微不足道,而且有很多陷阱。我已经实现了这个,我可以告诉你它确实有效,但它比看起来要难。你必须有一个非常好的低级PDF库,并且对PDF规范有非常透彻的理解。

我还没有讨论其他一些细节,比如颜色管理(如果你在托管CMYK上绘制DeviceRGB), PDF/A, PDF/X,传输注释和表单字段等。

如果这超出了你的能力,你应该寻找一个开源的嵌入式库,因为它做的差不多。压印是指在一张白纸上印上两页或两页以上的纸,目的是印刷一本书或传单。我也有一个商业解决方案。