1. 程式人生 > >PDF檔案中的圖片匯出

PDF檔案中的圖片匯出

最近要做一個PDF蓋章程式,研究了一下PDF,也在網上找了不少關於PDF的工具,發現都是使用已有的iSharepText或者PDFCreater做PDF處理,於是研究了一下PDF的格式文件,其實如果只匯出PDF圖片還是比較簡單的。

PDF文件說明中有體現了PDF是由多個PDFObject組成,再通過RootObject作為文件根節點處理頁面。而圖片也都是PDFObject的結構,所以只要匯出所有圖片型別的Object就可以了。

通過文件可以知道PDFObject都有型別標記,而圖片的型別就是Image,所以只要找到所有Image型別的PDFObject就可以了。

PDF文件結尾處有個固定結構的標記,叫startxref,用來標記xref表所在的位元組位置,而這個xref就是所有PDFObject的起始位元組位置的表,所以只要分析出每個Object起點,再找到/Type和/Image作為標記的Object,把Object對應Stream匯出就可以了。

Image對應的Stream有不同編碼方式,目前已知的有/CCITTFaxDecode模式和/DCTDecode模式,分別對應了CCIT4和JPG的編碼,不過對於/CCITTFaxDecode模式只有資料,需要自己給流結構增加Tiff檔案頭和檔案結尾,再儲存就可以識別為tiff,而DCTDecode是可以直接儲存為jpg檔案的。

xref在PDF1.4版本是使用了一個固定格式的文字來表示,第一行表示起始物件編號和物件數量,第二行開始為物件起始位元組位置,物件子版本號,物件是否有效三個部分總共20個位元組,用空格分開的。而到了PDF1.5xref就可以用一個PDFObject來表示,這個PDFObject可以用一個壓縮流和一個編碼來處理一個Stream,處理時根據PDFObject的DcodeParams 來設立解碼的引數,處理結束的Stream轉成位元組組後根據/Index和/W來獲取xref表的資料。W表示了每組xref資料的位元組數,比如[1 2 0]表示第一個欄位一個位元組,第二個欄位2個位元組,第三個欄位0位元組,再根據第一個欄位的內容來確認後面的位元組如何表示資料起點,第一個欄位只有3中資料,0表示未使用的PDFObject,1表示在使用的PDFObject,2表示壓縮的物件編號而非物件起始位置。後面的位元組根據w設定的位元組數表示一個地址數字,高位在前,地位在後的位元組組。

通過這些設定就可以分析出所有PDFObject,再根據Image對應的編碼模式判斷是否需要增加tiff檔案頭來儲存流。如果只是為了匯出Image這些就夠了,至於寫PDF可以以後再慢慢處理。