PDF格式研究簡介檔案結構Stream 編碼轉為XML相關工具OpenPDF訊息相關網站參考文獻最新修改簡體版English |
本文介紹了如何將 PDF 中的 stream 欄位轉換為純文字的方法,尤其著重在中文文字的編碼轉換方式上。 簡介PDF 是一種樹狀結構的文件,stream 是 PDF 中的一個重要的基本元件,因為所有的文字、影像等物件都是被編碼後放到 stream 物件之中,以下是一個範例片段
就是將 Hello World 等字串放到 stream 當中的一個範例。 中文的編碼方式由於 PDF 是一個跨語言、跨平台的文件格式,因此、所支援的編碼方式非常多樣,包含 Windows 標準 WinAnsiEncoding 字集,繁體中文的 BIG5 以及其擴充版本的倚天字集、簡體中文的 GB2312 字集、日文的 EUC 字集與 Shift-JIS 字集等等,其中、共有 14 種字集是預設在 Acrobat PDF Reader 中就有的,但並不包含中文、日文、韓文等亞洲字集,因此、需要使用到這些多國語言的環境時時,通常需要加入語言的特別安裝,這些安裝中有一個很重要的目錄稱為 CMap ,這是用來作語言編碼對照的檔案,例如:CMap/ETenms-B5-H 是繁體中文的倚天擴充字集對應到 Unicode 的編碼檔,以下是該檔案的一個小片段,
其中的 begincodespacerange 段落說明編碼的範圍第一段是由 00 到 80,第二段是由 A140 到 FEFE ,熟悉 big5 編碼的人應該就曉得這正是 big5 碼的編碼範圍,而第二段的 beginnotdefrange 代表 00 到 1F 是未使用的編碼區段。 第三段的 begincidrange 是真正的編碼對應表,其對應方式是一段一段的對應,例如:<a140> <a158> 99 代表
如此、各種編碼方式之間將可以正確正確的對應到標準的 PDF 預設字集 CID 上。 PDF 的預設字集 CID 並不是採用最廣為使用的 Unicode 字集,而是由 Adobe 公司所自行編碼的字集,稱為 Character Idientity 字集,簡稱為 CID 字集,所有的其他字集都會透過 CMap 檔案被對映到這個 CID 字集上,以便在顯示的時取得正確的字形,對於繁體中文而言,PDF 主要使用的除了標準的 CID 字集之外,最常被使用的就是 ETenms-B5-H 這個 CMap 所代表的字集,這是 BIG5 字集的倚天擴充版,關於這個字集的相關資訊可以在 Adobe 的協力開發網站上下載,網址是:
破解文字編碼在 PDF 中的中文編碼,並非都固定採用統一個方式,對於繁體中文而言,有時會用 ETenms-B5-H 來編,有時會用 CID 直接編碼, 以下我們再舉一個範例以說明中文編碼與解碼的問題。
上述範例中的 <BD75A457ADD3A448A4C6B0D1A6D2A4E5C46DBADEB27AA874B2CE> 其實是『線上個人化參考文獻管理系統』這段文字 但是我怎麼知到該段落所使用的編碼法是 BIG5 呢,當我們想寫一個程式去處理這些文字編碼時,就必需要先知到該 PDF 檔案是使用何種編碼法,但是、哪理有紀載這樣的資訊呢? 答案是在 Tf 這個代表字形的標記中,請仔細看上面的範例,其中的 /F1 24 Tf 所代表的就是後面文字段落所採用的字形資訊,代表 <BD75A457ADD3A448A4C6B0D1A6D2A4E5C46DBADEB27AA874B2CE> 這段資訊顯示時應該使用 F1 的字形,而且字形顯示時 要知道 /F1 字形所使用的編碼法,必需逆向追蹤該段落的父節點物件,由於 PDF 中並沒有記載逆向追蹤的資訊,因此、我們必需從上而下正向追蹤過來,才有辦法破解這個秘密。 首先、由於 PDF 是一個印表語言,因此最重要的物件是頁面,也就是範例中的 4 0 obj,屬性 /Type /Page ?明了這是一個頁面,另一個屬性 /Font 7 0 R ,記載了該頁所使用的字形是 /F1,字形資訊儲存在 7 0 這個物件當中,追蹤 7 0 obj 就可以看到下列段落
其中的 /Encoding 屬性說明了該頁面所使用的是 /ETenms-B5-H 的編碼法。 在取得編碼法之後,我們就可以利用 /Contents 這個屬性,得知該頁面的文字內容位於 5 0 R 之中,追蹤 5 0 obj 後就發現下列段落,因此、我們就知道應該用 ETenms-B5-H 這個 BIG5 的對映表來解碼。
若您要真正寫程式處理 PDF 檔案中的文字時,必須先解壓縮,然後再對 <…> 中的十六進位數字進行解碼,以對應到目標的 CID 編碼,然後在進行處理,但 CID 編碼法畢竟是 Adobe 公司私有的格式,並不容易作處理,因此、我們通長會將這個編碼再度轉換為 Unicode的標準編碼,然後再交給支援 Unicode 的函式庫去處理,像 Java 裏面的函式庫就可以輕易的處理 Unicode 編碼。 要將繁體中文 CID 轉為 unicode ,其對映表檔案是 Adobe-CNS1-UCS2 ,有關轉換為 unicode 的資訊也可在 Adobe 協力開發網http://partners.adobe.com/public/developer/en/pdf/chinese_t.zip 這個網址中找到。 另外、有時轉換為 unicode 的表格會被內嵌在 PDF 檔案中,然後在 /Font 物件中的 /ToUnicode 欄位內指定其物件編號,以下範例說明了這種情況,其中的 12 0 obj 是該嵌入式的 Cmap,可以用來將編碼轉換為 Unicode。
最後、有些 PDF 文件會將中文字放在 (…) 中以原始位元碼表示,而不是用 16 進位放在 <…> 中,此時,就需要將其內容直接取出,然後用 Encoding 與 ToUnicode 所指定的方式解碼,而不需要透過 16 進位了。 (但是要注意其中的跳出字元\n \t \b ….\ddd 等用法,這些字必需先被轉換成位元組的形式,才能處理)。 結語PostScript 是為了印表機而發展出來的語言,PDF也繼承了這樣的特性,因此、具有很好的列印品質,但要做加工則相當不易,本文探討了 PDF 的格式,並說明處理中文 PDF 時所經常遇到的一些問題與解決辦法,希望能對您有所幫助。 參考文獻
|
PDF 檔案內文字串 (Stream) 的編碼方式
page revision: 4, last edited: 19 Oct 2010 09:13
Post preview:
Close preview