使用C#開發pdf閱讀器初探(基於WPF,沒有使用開源庫)


前言 pdf是最流行的版式格式文件標准,已成為國際標准。pdf相關的開源軟件非常多,也基本能滿足日常需要了。相關商業軟件更是林林總總,幾乎應有盡有!似乎沒必要自己再獨立自主開發!但,本人基於以下考慮,決定自主研發一款pdf閱讀器。

  1)通過編寫pdf閱讀器,可以迅速的熟悉pdf文件的處理。pdf格式包含的內容非常多,僅僅通過查資料,很難掌握其內容。

  2)任何技術,只有自主可控,才能到達氣定神閑!使用開源軟件是簡單,萬一遇到問題,就是個坑!

  3)解決pdf與ofd互轉問題。ofd是國家標准,相關的處理軟件非常少。為了解決兩種格式文件互轉,必須了解pdf。

  4)本人此前開發了一款ofd閱讀器,積累了一些經驗。為開發pdf閱讀器增添了信心。

特別說明 本人花了幾周寫了這款閱讀器,驗證了pdf不同類型的數據處理,還遠遠到不了商用的要求。不積跬步無以至千里!本人會慢慢完善這款軟件,敬請期待。本人的參考資料有兩本英文書籍和pdf英文標准文檔。

程序界面: 點擊下載程序

pdf相關參考資料:

pdf文件結構簡介 

pdf總的內容結構如下:

 1)header: 有關pdf版本信息。最新版為 %PDF−1. 7

 2)Body:存儲具體數據,pdf就是由很多object組成的。每個object由dictionary和stream組成。dictionary存儲就是key、value字符對。dictionary是可以嵌套的,就是value有可能也是一個dictionary。

 3)Cross-Reference Table:交叉索引表。可以快速定位到具體object。便於隨機讀取object。

 4)Trailer:給出交叉索引表的位置。讀取pdf文件都是從最后開始讀的,所以Trailer一定是在文件最后。

 pdf處理總體結構

 object內容讀取

  交叉索引表能快速定位到某個object的位置,讀取object內容不難,關鍵是分析dictionary。dictionary是可以嵌套,就是dictionary的內容還有dictionary。快速解析出所有的dictionary是處理的關鍵。典型的dictionary結構如下:

<<
/Annots 68 0 R /BleedBox [0 0 504 661.5] /Contents [51 0 R] /CropBox [0 0 504 661.5] /MediaBox [0 0 504 661.5] /Parent 4334 0 R /Resources << //嵌套dictionary
/ColorSpace <</CS1 62 0 R>>  //2次嵌套dictionary
/Font <</F1 7 0 R/F2 11 0 R/F3 13 0 R/F4 53 0 R>> //2次嵌套dictionary
/ProcSet [/PDF/Text/ImageB/ImageC] //數組
/XObject <</I1 54 0 R/I2 56 0 R/I3 60 0 R>>//2次嵌套dictionary
>>

/Type /Page >>

頁面內容分析

  頁面內容由系列操作數和操作符組成。所有的操作數和操作符在同一個文本中,所以要快速的將操作數和操作符組成可以執行的操作對。

0 0 515.95 728.6 re
W* n
0 w
2 M
2 J
2 j
0 0 0 RG
BT
0 0 0 rg
/FT8 180 Tf
/GS13 gs
0.05 0 0 -0.05 187.68 676.49 Tm
<35BE>Tj 180 0 TD<1D5F>Tj 180 0 TD<4205>Tj 180 0 TD<4EC8>Tj
ET

  字符都是存在()或<>中,除去字符和數字,就是操作符。如上文W*、n都是操作符;<35BE>為16進制字符對應的key,具體代表哪個字,需要到查字符表。這里的35BE並不是unicode字符對應的值,還需要再查表。如下圖:

beginbfchar
<0019> <0036>
<35BE> <0037>
<001B> <0038>
<001C> <0039>
endbfchar

  <35BE>對應的是<0037>。該表存在字體資源文件object中。

 頁面顯示

  坐標系變換

  理清不同坐標系之間的關系是處理的關鍵。坐標系分為:Device Space(設備坐標空間)、User Space(設備坐標空間)、text space(文本坐標空間)等。

  繪畫上下文設置 

  當前繪畫的狀態(畫筆、畫刷等)是保存在棧中,會有入棧出棧操作。

  特殊畫刷處理

  pdf有一種畫刷,比如漸變色,這個很難找到現成的畫刷使用。我使用的是ImageBrush,就是使用圖片作為畫刷。在內存中創建可擦寫的圖片,可以精確控制每個像素的值。根據pdf標准提供的算法,計算每個像素的值。

  pdf的顯示大體分為三種:曲線、文本、圖片。其中曲線的顯示是比較麻煩的,關鍵是將pdf標准的描述與wpf曲線操作對應起來。

pdf閱讀器開發說明

  如果完全參數標准文件開發,是比較枯燥,感覺慢慢長路看不到盡頭。我采用是單個功能各個擊破的方法,能很快見到開發成果。我使用的參考書是《PDF Explained》,100多頁,只是對pdf做大體介紹,但是各個功能點都有所提及。我就參照該書提供的示例文件,逐步驗證每個文件。

  每種顯示都有多種處理方法,每個軟件生成pdf的風格是不同的。對特定的軟件生成的pdf做幾次驗證后,基本可以保證該軟件生成的pdf都可以正常顯示。

  wps是可以直接將doc文件轉換為pdf的。我對wps生成的pdf做了測試,經過幾次調試,現在基本可以正常處理wps生成的pdf文件。

  后記 對於開發pdf閱讀器這類軟件,以前都是不敢想象的。像這種復雜的軟件,必須遵循一定的設計模式、正確建立域模型。所以開發這類軟件,對pdf標准的理解是否深刻並非關鍵,關鍵還是編程的功底。軟件的外在表現千奇百態,但內在邏輯具有類比性的。繼承、封裝、多態、SOLID設計准則這些並不難理解,但是要達到應用自如還需要反復錘煉。把握好每個細節,正確運用設計准則,一步一個腳印,最終會將不可能變成可能!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM