我的一位朋友在报纸上工作并在星期一问我这个问题,我无法确认是否可能。
我知道可以使用PHP合并2个PDF(因为我已经看到许多其他问题已经回答),但我不确定的是,如果我可以合并半页PDF来填充另一个空间PDF。
想象一下: 我有PDF1:半页PDF,然后我有3页PDF:Pdf2。 在PDF2的第一页中,我有一个空的空间来容纳PDF1。
我可以这样做吗?如何?
答案 0 :(得分:0)
我不能给你具体的源代码,但我可以解释如何在非常低的水平上完成它。此外,您正在寻找的东西类似于出版业中所谓的定位。
您的开始方式与合并相同,这意味着从其他文档中提取页面。您必须递归地引入页面的所有依赖项。但请注意避免无限循环,这些循环确实存在于PDF中,因此您必须跟踪被访问对象。不要使用递归函数,因为你的堆栈很容易溢出,PDF引用可以非常深入。您应该在堆上实现遍历递归(Depth First Search很好)。
在PDF上标记PDF的关键是将源页面对象转换为XObject形式(不要与AcroForms或可填写的表单字段混合)。 XObject表单与Page对象非常相似,但有以下例外:
/Type /Page
变为/Type /XObject /Subtype /Form
。MediaBox
和CropBox
一起成为表单中的/BBox
。但是要小心,它们都可以通过页面树继承,因此你必须寻找继承的属性。Rotate
(也是可继承的)变为Matrix
,这是一个转换(旋转)矩阵,而不是角度。Resources
,Group
和Metadata
可以保持不变,并添加到表单对象中。Contents
流传输到表单。但是,页面Contents
是一个外部对象,可能是一个数组,这意味着您需要合并这些部分。 XObject表单是一个流对象。完成此操作后,您所要做的就是在新页面上绘制XObject表单。您必须为XObject生成唯一名称并将其添加到页面Resources
。绘画本身是一系列cm
和Do
运算符,就像绘制图像一样。如果您需要裁剪原始内容,则还需要在Do
之前设置剪切路径。
毋庸置疑,这远非微不足道,而且存在很多陷阱。我已经实现了这一点,我可以告诉你它确实有效,但它比它看起来更难。您必须拥有一个非常好的低级PDF库,并且对PDF规范有非常透彻的了解。
我还没有讨论过其他一些细节,例如色彩管理(如果你在托管CMYK上绘制DeviceRGB怎么办),PDF / A,PDF / X,转移注释和表单字段等等。
如果这超出了你的范围,你应该寻找一个开源的定位库,因为它几乎完全相同。定位意味着将两页或更多页放在一张空白纸上,目的是打印书籍或传单。我也有商业解决方案。