2011-08-11 54 views
1

我的一位朋友在一家報社工作,週一問我這個問題,我無法確認是否有可能。用PHP合併兩個半頁PDF文檔

我知道可以使用PHP合併2個PDF(因爲我已經看到很多其他問題已經回答),但是我不確定的是,如果我可以合併一個半頁PDF以填充一個空間另一個PDF。

想象一下: 我有PDF1:半頁PDF,然後我有一個3頁PDF:Pdf2。 在PDF2的第一頁中,我有一個空白空間以適合PDF1。

我可以這樣做嗎?怎麼樣?

回答

0

我不能給你具體的源代碼,但我可以解釋如何在非常低的水平上做到這一點。此外,您要找的內容與出版行業中所謂的拼版相似。

您從合併的方式開始,這意味着從另一個文檔拉入頁面。您必須遞歸地引入頁面的所有依賴關係。但要小心避免PDF中存在的無限循環,因此您必須跟蹤訪問的對象。不要使用遞歸函數,因爲你的堆棧很容易溢出,PDF引用可能非常深。你應該在堆上實現遍歷遞歸(Depth First Search很好)。

在PDF上打印PDF的關鍵是將源頁面對象轉換爲XObject表單(不要與AcroForms或可填寫的表單域混合)。一個x對象形式非常類似於Page對象,但有以下例外:

  • /Type /Page變得/Type /XObject /Subtype /Form
  • 頁面MediaBoxCropBox一起成爲/BBox的形式。但要小心,它們都可以通過頁面樹繼承,因此您必須查找繼承的屬性。
  • 頁面Rotate(也可繼承)變成Matrix,它是一個轉換(旋轉)矩陣,而不是一個角度。
  • 頁面的Resources,GroupMetadata可以保持不變並添加到表單對象。
  • 頁面Contents流必須轉移到窗體。但是,頁面Contents是一個外部對象,可能是一個數組,這意味着您需要合併這些部分。 XObject表單是一個流對象。
  • 所有其他屬性都很棘手,如果您不確定,您可能會忽略它們。

完成此操作後,您所要做的就是在新頁面上繪製XObject表單。您必須爲XObject生成一個唯一的名稱,並將其添加到頁面的Resources。繪畫本身是一系列cmDo操作員,就像繪製圖像一樣。如果您需要剪裁原始內容,則還需要在Do之前設置剪切路徑。

不用說,這遠非微不足道,而且還有很多缺陷。我已經實現了這一點,我可以告訴你它確實有效,但它似乎比看起來更難。您必須擁有一個非常好的低級PDF庫,並且對PDF規範有非常透徹的理解。

我還沒有討論其他一些細節,如色彩管理(如果你畫DeviceRGB上管理CMYK),PDF/A,PDF/X,轉移註釋和表單域等

如果這超出了你,你應該尋找一個開源的拼版庫,因爲它幾乎是一樣的。拼版意味着在一張白紙上放置兩頁或更多頁,以打印書或傳單。我也有一個商業解決方案。