使用PHP合并两个半页PDF文档

时间:2011-08-11 15:20:57

标签: php pdf merge

我的一位朋友在报纸上工作并在星期一问我这个问题,我无法确认是否可能。

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

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

我可以这样做吗?如何?

1 个答案:

答案 0 :(得分:0)

我不能给你具体的源代码,但我可以解释如何在非常低的水平上完成它。此外,您正在寻找的东西类似于出版业中所谓的定位。

您的开始方式与合并相同,这意味着从其他文档中提取页面。您必须递归地引入页面的所有依赖项。但请注意避免无限循环,这些循环确实存在于PDF中,因此您必须跟踪被访问对象。不要使用递归函数,因为你的堆栈很容易溢出,PDF引用可以非常深入。您应该在堆上实现遍历递归(Depth First Search很好)。

在PDF上标记PDF的关键是将源页面对象转换为XObject形式(不要与AcroForms或可填写的表单字段混合)。 XObject表单与Page对象非常相似,但有以下例外:

  • /Type /Page变为/Type /XObject /Subtype /Form
  • 页面MediaBoxCropBox一起成为表单中的/BBox。但是要小心,它们都可以通过页面树继承,因此你必须寻找继承的属性。
  • 页面Rotate(也是可继承的)变为Matrix,这是一个转换(旋转)矩阵,而不是角度。
  • 页面的ResourcesGroupMetadata可以保持不变,并添加到表单对象中。
  • 必须将页面Contents流传输到表单。但是,页面Contents是一个外部对象,可能是一个数组,这意味着您需要合并这些部分。 XObject表单是一个流对象。
  • 所有其他属性都很棘手,如果您不确定,可能会忽略它们。

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

毋庸置疑,这远非微不足道,而且存在很多陷阱。我已经实现了这一点,我可以告诉你它确实有效,但它比它看起来更难。您必须拥有一个非常好的低级PDF库,并且对PDF规范有非常透彻的了解。

我还没有讨论过其他一些细节,例如色彩管理(如果你在托管CMYK上绘制DeviceRGB怎么办),PDF / A,PDF / X,转移注释和表单字段等等。

如果这超出了你的范围,你应该寻找一个开源的定位库,因为它几乎完全相同。定位意味着将两页或更多页放在一张空白纸上,目的是打印书籍或传单。我也有商业解决方案。