DjVu轉PDF


作者:馬健
郵箱:stronghorse_mj@hotmail.com
發布:2009.09.22
更新:
2012.06.11
針對PdfToy的新進展,更新了相關內容。

1 引言
2 理論
3 實現
    3.1 MRC模型的轉換
        3.1.1 單層DjVu
        3.1.2 3層DjVu
        3.1.3 2層DjVu(彩色文本)
    3.2 圖像的轉換
        3.2.1 JB2轉JBig2
        3.2.2 IW44轉JPEG 2000
        3.2.3 JPEG與CCITT G4的轉換
    3.3 隱藏文本的轉換
    3.4 目錄的轉換
    3.5 其他部分的轉換
4 結論
5 引申
    5.1 用DjVu技術制作PDF
    5.2 反向轉換
    5.3 PDF瀏覽器限制


1 引言

在掃描電子文檔領域,PDF與DjVu各有特色,也都各有一批堅定的支持者,所以網上經常能看到求助實現兩種格式互相轉換的帖子——都希望能轉成自己或別人喜歡的格式。網上提供的解決方案也多種多樣,從最簡單的虛擬打印(PDF與DjVu均有虛擬打印機),到使用專門的工具 (單步)或工具集合(多步)轉換都有。

出於興趣,我最近也在這方面進行了一些技術探索,不過重點不在結果本身(我個人一直不主張在不同格式之間轉來轉去窮折騰),而在於轉換的過程:希望能從技術角度比較PDF與DjVu的模型與內部數據壓縮算法,盡量實現無損轉換,同時保持文件長度變化不大。

本文就是上述過程的一個記錄。

2 理論

按我個人的理解,DjVu的高壓縮比主要來自以下幾個方面:

  • 基於MRC(Mixed Raster Content,參見ISO/IEC 16485)模型的分層結構:將掃描圖像分解成前景、背景、蒙板層,然后針對不同層的特點,采用最適合的圖像壓縮算法。在表達文字、圖像混合的點陣圖像時,這種方法無疑比傳統不分層的、眉毛胡子一把抓的靜態圖像壓縮格式(如JPEG、JPEG 2000、PNG、TIFF、GIF等)更優秀。另外按照ISO/IEC 16485的建議,如果對圖像先分割成子區域(strip)再進行分層,或采用N層結構,可能獲得更高的壓縮性能。不過DjVu大概認為追求這樣的性能提高不太值得,所以一直堅持采用MRC的基本三層模型。
  • 在分層的基礎上,DjVu從閱讀心理出發,認為閱讀者對掃描頁面文字部分的關注度,要高於對插圖、底紋的關注度。因此對於文字部分,不對像素尺寸進行縮減, 保持盡可能高的清晰度和分辨率;而對於插圖、底紋部分,一般先進行縮圖,然后再有損壓縮——通常長、寬縮至原來的1/3~1/12,顯示的時候再放大回來。簡單算一下就可以知道,就算長、寬只縮至1/3,圖像面積也只有原來的1/9大, 即還沒怎么着呢就輕松達到1:9的壓縮比,自然能夠大大減小最終的文件長度,付出的代價是:很多DjVu文件的插圖看起來模模糊糊的,這其中的原因除了有損壓縮外,圖像縮放更主要。DjVu文件各層的像素尺寸,可以從DjVuToy導出的DjVu文件信息中看到,有興趣的不妨看一看。那些經常問“為什么我看到的DjVu這么模糊?”或“為什么國外的DjVu比國內的DjVu更清晰?”的人,更應該好好看看。
  • 在編碼方面,DjVu的文字層采用JB2壓縮算法。這種算法的核心思想是:把整頁文字切分成一個個符號(shape),相同的符號不再重復編碼,這樣整頁文字可以用一個無重復的符號集合(稱為“字典”,dictionary)、一個頁面描述集合來表示。單條頁面描述可以用三元組(idx,x,y)表示,idx代表符號在字典中的序號,(x,y)是該符號的顯示位置,說白了每條頁面描述的意思就是:在(x,y)處顯示編號為idx的符號。采用這種方式,不僅頁面中的空白部分不再需要編碼,而且對於印刷字體(尤其是字母文字), 每一頁中符號的重復程度是很可觀的,這些重復的符號編碼也都可以省略了,所以壓縮比要比常規靜態圖像要大。不過這種算法的問題是:如何判斷兩個符號是相同的?畢竟圖像是掃描出來的, 二值化后字符邊緣充滿了毛刺,要說兩個字一個像素不差不太可能,總要有一個容忍程度,差異超過此容忍程度即認為兩個符號不同,否則認為相同。在常規DjVu制作軟件中, 一般提供給用戶三種選擇:無損(lossless)、清潔(clean)、有損(lossy),容忍程度從小到大,而最終文件長度則從大到小。DjVu一向標榜的就是高壓縮比,所以常規制作軟件的缺省選擇都是有損,這樣就可能因為把相似字誤判為相同字而出現錯別字:
    http://djvu.org/forum/phpbb/viewtopic.php?t=659
    http://readfree.net/bbs/read.php?tid=277235
    這個問題是JB2有損壓縮的原罪,理論上很難完全避免,實際上各DjVu生成引擎都會在內部進行一些判別以求彌補,但效果如何誰也說不清。所以在有足夠的證據(我很懷疑有誰能提出這樣的證據)證明某個DjVu引擎不會對中文相似字進行誤判之前,我絕對不可能把我自己需要保留的文件壓縮成有損JB2。當然,給別人看的就另當別論了,錯不錯的關我P事?
    另外這種判別與圖像的掃描DPI密切相關,DPI值低於300時誤判的可能性要比300 DPI及其以上的誤判可能性更大。按照國外掃描界的要求(參見大名鼎鼎的《The Scan and Share tutorial version 1.07》),掃描時應該用300 DPI灰度掃描,然后用軟件放大至600 DPI,再處理成DjVu。這就是為什么有些人總覺得國外的DjVu比國內的更清晰的原因:大家的DPI不一樣!
  • DjVu的插圖、底紋部分通常采用IW44壓縮算法,這種算法基於小波(Wavelet)分析,原理基礎和JPEG 2000差不多,一般采用較高壓縮比,代價是圖像質量用肉眼就能看出是有損的。

與ISO 32000-1相對照,其實以上特性在PDF中也有:

  • PDF的transparent imaging model支持多層結構,包括透明、半透明,比DjVu的模型結構復雜多了。
  • 從PDF 1.4(對應Acrobat5)開始支持JBig2壓縮,這種壓縮算法在核心思想上(參見ISO/IEC 32000-1:2008第7.4.7節、ISO/IEC 14492:2001)與DjVu的JB2壓縮一模一樣。不過JBig2考慮的范圍更廣泛一些,除文字、線型圖外,還考慮到半調(halftone)圖像等,因此定義遠比JB2復雜。換句話說,JB2數據流可以完全轉換成JBig2數據流,但是反向就不一定了——JBig2中的某些東西在JB2中沒有對應。
  • 從PDF 1.5(對應Acrobat6)開始支持JPEG 2000壓縮,這種壓縮算法的理論基礎與DjVu的IW44壓縮一樣,都是基於小波分析。從實際圖像測試結果看,對於同一張連續色調圖像,這兩種算法在同樣的壓縮比下,最終的視覺效果差別不明顯。換句話說,對於同一張圖像,這兩種算法壓縮出來的文件長度可以差不多,視覺效果也差不多。

所以,在理論上,大多數DjVu可以在轉換成PDF時,做到在文件長度變化不大(變化還是有,畢竟文件結構方面存在差異)的情況下,數據無損(JB2->JBig2)或視覺無損(IW44->JPEG 2000)。

注意我說的是“大多數DjVu”,因為例外總是存在的。

3 實現

理論說上一大堆,如果沒有一個實際實現,總還是覺得有點虛。所以我就以FreePic2Pdf的PDF生成引擎為基礎,加入對DjVu的支持,最終在DjVuToy中實現了DjVu轉PDF功能:一次可以轉換一本書, 除圖像外還包括多級書簽、隱藏文本,但不包括注釋、縮略圖等。

下面分別介紹一下其中幾個關鍵技術的實現原理和方法,及對最終結果的驗證。

3.1 MRC模型的轉換

前面說過,DjVu的基本圖像模型是ISO/IEC 16485 MRC三層模型,但並非所有DjVu都湊足了三層,有些只有單層或2層。

  • 單層DjVu:又稱為Photo DjVu(彩色、灰度)或Bi-Level DjVu(黑白),一頁只有一層圖像,彩色、灰度圖像可以采用IW44或JPEG壓縮,黑白圖像采用JB2或CCITT G4壓縮。
  • 2層DjVu:又稱為彩色文本(Color Text)DjVu,即只有前景層(JB2壓縮或CCITT G4壓縮)和背景層(IW44或JPEG壓縮),但前景層允許帶顏色,此時的JB2又稱為Colorized JB2。這是對原JBig2標准的擴展,為DjVu所獨有。
  • 3層DjVu,即包含蒙板層、前景層、背景層這3層的DjVu。蒙板層為黑白圖像,可以采用JB2或CCITT G4壓縮;前景層、背景層為灰度或彩色圖像,可以采用IW44或JPEG壓縮。

下面針對這三種情況,討論DjVu的MRC到PDF圖像模型的轉換。

3.1.1 單層DjVu

單層DjVu其實就是單一的圖像,與PDF中的圖像可以直接建立對應關系,因此單層DjVu轉PDF不涉及太多模型層面的東西,轉換的時候將整幅圖像插入PDF頁面中即可。

3.1.2 3層DjVu

3層DjVu也不復雜,PDF的圖像模型中同樣允許使用蒙板,甚至允許指定蒙板的透明度(權重),因此3層DjVu轉PDF,在模型上也沒有太多的問題,只在於怎么選擇合適的蒙板表示而已。

最終我選擇了用SMask實現,原因很簡單:用這種方式產生的PDF在Acrobat中瀏覽時可以指定背景色 ,即成為常說的“透明背景PDF”。

這個例子是一個三層結構的DjVu文件及用DjVuToy轉換后的PDF文件,有興趣的可以比較一下顯示效果。內部數據的比較結果如下:

  • DjVu:蒙板層像素尺寸2774×3543,數據流長度26896字節;前景層232×296(長、寬僅為蒙板層的1/12),數據流長度5138字節;背景層925×1181(長、寬僅為蒙板層的1/3),數據流長度34334字節。
  • PDF:各層像素尺寸與DjVu一樣,數據流長度分別是:27424字節、5083字節、34386字節,差別不大。

各位如果有興趣,不妨把這個例子DjVu另存為單張靜態圖像,可以看到文件長度急劇膨脹,對照一下將有助於理解我前面說的DjVu高壓縮比的原因

DjVu轉PDF的官方轉換軟件Caminova DocumentExpress Enterprise 7.5(簡稱deent75)在轉換多層DjVu的時候,有一個噱頭:轉換出來的PDF帶有圖層控制,可以在用Acrobat瀏覽的時候,指定顯示前景層或背景層。我個人覺得圖層控制會增加PDF文件的長度,而且支持圖層控制的PDF瀏覽器和會用的人都很少,所以就沒管它。

DjVuToy的噱頭是:轉換出來的PDF是背景透明的,不論是單層還是多層,用戶在瀏覽的時候都可以指定背景色。

3.1.3 2層DjVu(彩色文本)

“彩色文本”是DjVu的一個獨門絕技。如果頁面中含有彩色文字,在DjVu中可以有兩種實現方法(參見Lizardtech公司2005年出版發行的《Lizardtech DjVu Reference DjVu V3》第7.1.3.1節“Foreground Encoding”):

  • 常規三層法:文字輪廓用JB2壓縮,作為蒙板層(Sjbz);顏色部分用IW44壓縮,作為前景層(FG44)。上面這個例子就采用這樣的技術。為了追求高壓縮比,通常對前景層進行大比例縮圖(如上面這個例子長寬縮至1/12),這樣在還原顯示的時候,文字顏色看起來可能會有點怪異,因為 縮放后的前景層總會與原來的有點差異。
  • 彩色文字法:文字輪廓用JB2壓縮,成為蒙板層(Sjbz),然后對每個符號的顏色進行編碼,成為前景顏色層(FGbz)。

兩種方法相比較,后者的編碼效率要更高一些,顯示時的文字顏色也比較純正,缺點是每個符號的顏色必須是單一純色,不能出現變化(如漸變色文字)。而前者的適應范圍無疑要更廣泛一些,壓縮比問題通常通過縮圖解決,如長寬縮至1/12,則面積僅為原先的1/144,還沒開始編碼就輕松超過1:100的壓縮比。

以我對PDF的了解,采用彩色文字的DjVu如果想轉換成PDF,最無損的辦法大概是:把Sjbz數據段拆成“字典”和“頁面描述”兩個部分,字典中的符號封裝成點陣字體嵌入PDF,頁面描述中的 內容轉換成PDF的字符輸出指令,FGbz中的顏色描述則轉換成PDF的前景色設置指令。顯示的時候,按照指定的顏色顯示字符,字符點陣來自內嵌字體。

這種方法好是好,但是其中的復雜性我只是想一想就失去了嘗試的勇氣。所以最終還是偷了個懶:把2層結構轉換成常規3層結構。官方轉換軟件deent75用的也是這個方法,不過DjVuToy比deent75多了一個選擇:可以選擇轉換時前景層的縮圖比例。

在2層模型轉成3層模型的時候,需要先把彩色前景層還原出來,然后再縮圖成前景層,原蒙板層、背景層則不變,這樣就將2層變成了3層。如果前景層不縮圖,則轉換出來的PDF在視覺效果上與原始DjVu是完全一樣的,但是文件長度會大增——多出來的前景層是灰度或彩色,不論采用JPEG還是JPEG 2000壓縮,如果畫面尺寸降不下來,文件長度也就降不下來。

在deent75中,對前景層一律縮圖至原像素長、寬的1/12,而DjVuToy的缺省值與deent75相同,但如果對質量很在意而對文件長度不在意,也可以手工設置縮圖比例。

另外前景層圖像的生成也很有講究,deent75的生成方法我模仿了很久也沒有模仿出來,現在這個是經過大量實驗得到的,在文件長度、圖像質量方面不見得比deent75差。

3.2 圖像的轉換

3.2.1 JB2轉JBig2

這個部分初看起來似乎沒啥懸念:把JB2中的字典、頁面描述解碼出來,按照JBig2的要求重新編碼、封裝即可,中間不需要全圖解碼成位圖后再重新分割、聚類。

但是實際做過以后才會知道,這中間還是有講究的:如果不對字典進行處理,直接就編碼、封裝,最終的結果大概會比最初的JB2數據流長約20%。其中的原因我也是看了Adam Langleyjbig2enc才明白:如果字典中的某些符號在頁面描述中多次出現,可以把這些符號單獨編成一個字典,那些只出現一次的符號編成另外一個字典,這樣可以減小頁面描述中的索引位數,最終減小整個數據流長度。這種技術沒看到有誰專門命名,姑且稱之為“字典二次編碼”技術。這種技術對多頁共用字典固然有影響, 對單頁獨享字典也有影響。

除了上述字典二次編碼技術外,JBig2的算術編碼效率也對最終數據流長度有影響,不過這部分太復雜了,不是一般人能搞定的。

對最終編碼結果的驗證則很簡單:

  • 用DjVuToy可以導出DjVu文件結構,用PdfToy或免費開源的PdfView可以導出PDF文件結構,比較一下其中JB2、JBig2數據流的長度,即可知道編碼效率的差異。從實際測試結果看,差異有一些,但是絕對沒有網上常見的DjVu宣傳資料上宣稱的那么大。
  • 用PdfToy或UnicornViewer 0.17以上版本可將PDF中的JBig2數據流轉換成JB2並封裝成DjVu文件,用DjVuToy可導出轉換前后的DjVu文件的字典、頁面描述,用FindDupFile可驗證這兩個文件的字典完全相同,頁面描述用Excel重新排序后也可以驗證完全相同,因此可認為JB2轉JBig2及反向的JBig2轉JB2過程均是完全無損的。

這樣的驗證其實說明一件事:對於采用JB2壓縮的單層DjVu,可以用DjVuToy無損轉換成PDF,文件長度也差不多。

另外JB2與JBig2的相似性也不是偶然的,在AT&T的Patrick Haffner、Leon Bottou、Yann Lecun與Lizardtech公司的Luc Vincent合著的論文《A General Segmentation Scheme For DjVu Document Compression》第2章中,對JB2算法的來歷進行了介紹:

The mask image is encoded with a new bi-level image compression algorithm called JBZ or DjVuBitonal. It is a variation on AT&T's proposal to the emerging JBIG2 standard. The basic idea of JB2 is locate individual shapes on the page (such as characters), and use a shape clustering algorithm to find similarities between shapes. Shapes that are representative of each cluster (or in a cluster by themselves) are coded as individual bitmaps with a method similar to JBIG1.

看來不僅名字相似,JB2與JBig2追到根子上還有血緣關系,不過似乎JBig2后來又發展出了一些新花樣,而JB2就此頹廢了——所托非人啊!

3.2.2 IW44轉JPEG 2000

我本人的數學基礎不太好,對小波分析更是望而生畏,所以沒有研究是否可能像JB2轉JBig2那樣,在不解碼成位圖的情況下實現直接轉換,而是采用了一個偷懶的笨辦法:先把IW44解碼成位圖,根據解碼前后的數據流長度可以算出壓縮比,然后按照這個壓縮比,再把位圖壓縮成JPEG 2000。這里面的關鍵就是:JPEG 2000壓縮允許指定壓縮比,保證壓縮出來的數據流長度在指定的范圍內。

對最終編碼結果的驗證也很簡單:

  • 用DjVuToy導出DjVu文件結構,用PdfToy或PdfView導出PDF文件結構,比較其中BG44、FG44與JPXDecode數據流的長度,即可知道編碼效率的差異。從實際測試結果看,差異可以忽略。
  • 用PdfToy或UnicornViewer 0.17以上版本可以將PDF中的JPEG 2000圖像無損導出,用圖像比較軟件可以從統計角度定量比較二者的差異,也可以直接用肉眼比較一下,在我看來都差不多,基本上可以認為是“視覺無損”,除非壓縮率超過了一定限度。

如果有誰對小波比較精通,不妨對IW44和JPEG 2000進行一下深入研究,我總覺得這二者是可以直接轉換的——研究有成果了別忘記通知我一聲。

上面的JB2、IW44驗證說明:對於3層DjVu,在用DjVuToy轉換成PDF后,模板層肯定是無損的,前景層、背景層視覺無損,文件長度差異不大。

對於2層DjVu,由於需要補充前景層,轉換后文件長度增加會明顯,前景層縮圖造成的影響在某些情況下也是視覺可查的。

3.2.3 JPEG與CCITT G4的轉換

按照《Lizardtech DjVu Reference DjVu V3》的規定,DjVu中的蒙板層除JB2壓縮外,還可以采用CCITT G4壓縮,其Chunk ID為Smmr;前景層、背景層除IW44外,還允許采用JPEG壓縮,其Chunk ID分別為FGjp、BGjp。

由於這兩種壓縮算法的壓縮效率與JB2、IW44相差太多,因此采用這兩種壓縮算法的DjVu文件在現實中根本沒有,我自己測試用的文件也是用軟件特意制作出來的。

PDF本身支持CCITT G4、JPEG壓縮,因此采用這兩種壓縮的圖像可以無損轉換至PDF——CCITT G4可能還需要重新編碼,JPEG圖像整個嵌進去即可。

3.3 隱藏文本的轉換

DjVu的設計初衷是針對掃描圖像,但也提供隱藏文本功能,方便對文檔內容進行檢索、復制等。

DjVu中的隱藏文本通過OCR獲得,帶隱藏文本的DjVu習慣上稱為“雙層DjVu”,這其實是從“雙層PDF”沿用過來的——用掃描圖像制作的PDF,也可以通過OCR生成隱藏文本。

在DjVu轉PDF的過程中,如果DjVu已經有隱藏文字,自然希望能夠直接轉過去,不用再OCR。但其中涉及到DjVu與PDF的一個本質區別。

DjVu的設計目的從未變過,就是針對掃描圖像,文字不過是輔助,因此DjVu中的文字是真正的“隱藏”文字,只有文字的編碼(utf-8)、文字的位置,但不含任何字體信息,因此理論上是顯示不出文字的,除非再額外指定字體。

PDF中的文字則與圖像並列,顯示出來是正常的,隱藏起來不過是特例。因此在PDF中,文字除了有編碼、顯示位置、顯示比例外,還要有字體信息。所以在將DjVu中的隱藏文本轉換成PDF時,麻煩就麻煩在字體上。

PDF中的字體可以是內嵌字體,也可以是外掛字體。具體哪種更優,各人看法不同。我自己是比較傾向於外掛字體。

PDF中對外掛字體有特殊規定,要求所有PDF瀏覽器均支持的14種標准字體中,就有9種是針對西歐拉丁語系(Latin 1),對CJK(中、日、韓)則規定了額外的標准字體,是否支持由各瀏覽器自行決定。Acrobat如果裝了亞洲語言包,是能支持Adobe的CJK標准字體的。UnicornViewer是中國人開發的,對CJK的支持就更不用說了。

換句話說,如果采用外掛字體,其實只有Latin 1(西歐11國)和CJK(簡、繁、日、韓)才能保證平台通用性,其它語言,如俄語,理論上說可以指定Windows的TrueType字體作為外掛字體,但其平台通用性無法保證。

在用deent75轉換DjVu成PDF時,對於隱藏文字也只針對Latin 1和CJK的外掛字體轉換。DjVuToy在隱藏文本轉換方面完全學自deent75,其位置與deent75的差異在小數點后第4位——DjVuToy我覺得到小數點后第4位 已經足夠,deent75覺得還應該保留更多的位數。

DjVuToy在模仿deent75的基礎上,也做了一些改進:

  • 強化了對中、日、韓豎排文字的支持。deent75完全沒有豎排的概念,這點很令人詫異,畢竟這家公司的總部就在亞洲。
  • 允許將word合並成line。合並后單個word的位置可能出現變化,但是數據流長度大大減小,校對的時候也簡單許多。
  • deent75轉換出來的雙層PDF是“圖壓字”,即隱藏文字在底層,圖像在上層。這樣的處理存在一些弊端,因此DjVuToy向Acrobat學習,采用了“字壓圖”的方法,即圖像在底層,隱藏文字在上層。

總之,有些東西是用出來的。

3.4 目錄的轉換

目錄在PDF中稱為Outline,在DjVu中稱為Bookmark、Contents,其實就是在瀏覽的時候,左側顯示出來的分級大綱。

DjVu中的目錄其實比PDF簡單得多,而且不能實現對跳轉位置的精細控制:在PDF中,通過點擊目錄項既可以跳轉到某一頁,也可以跳轉到頁中的某個位置,而DjVu只能跳轉到頁,這點和PDG的目錄差不多。

DjVuToy轉換DjVu目錄的時候就是直轉,即將DjVu中的utf-8轉換成PDF的Unicode,頁碼也照轉。不過我也偷了點懶:DjVu中的目錄允許跳轉到某個文件或某個URL,DjVuToy對這些情況就無視了。

3.5 其他部分的轉換

在DjVu中,還有注釋、縮略圖等內容,這些在PDF中都有對應,理論上說在轉換成PDF也應該能轉過去,不過我看官方的deent75也沒管這些,所以我也都無視了,反正這些東東對我來說也根本碰不到,不值得花時間。

4 結論

綜上所述,大多數DjVu在轉換成PDF時,可以在文件長度變化不大的情況下,做到數據無損(JB2轉JBig2)或視覺無損(IW44轉JPEG 2000),並能將隱藏文本、目錄等一起轉換過去,前提是轉換的方法和工具得當。

從這一點上說,“DjVu格式的壓縮比高於PDF格式”的觀點其實是不成立的——在“格式”上PDF也可以實現DjVu的高壓縮比,因此二者的差異不在於“格式”,而在於把靜態圖像轉換成最終“格式”的工具和方法。

5 引申

5.1 用DjVu技術制作PDF

目前常見的PDF制作工具,包括Acrobat,在將靜態圖像轉換成PDF時,多半采用“嵌入”的方式,即將整個靜態圖像數據流甚至文件嵌入PDF文件中,不進行進一步的處理 (如按MRC模型分層)。這種方法的好處是技術簡單、實現方便、圖像可以完全無損,缺點是經常有人抱怨這樣做出來的PDF文件比DjVu大得多。

而從前面的描述來看,DjVu的高壓縮比與它的“分層結構、按需編碼”有直接關系,而這是可以復制到PDF中來的。因此我認為如果想提高掃描版PDF的壓縮率,可以在PDF制作軟件上進行改進:引入商業DjVu制作軟件的內核或引擎,對需要轉換成PDF的掃描圖像進行分層,然后按照分層結果選擇最有效的圖像壓縮算法。即把上面說的“圖像->DjVu->PDF”過程簡化成“圖像->PDF”,中間這一步在PDF制作軟件內部悄悄完成了。

當然,如果不嫌麻煩,或者有OCR的技術積累,也可以自己去做分層的開發,但最終結果是一樣的。其實在我第一次看到用luratech公司的產品制作出來的高壓縮比PDF時,我就懷疑他們是這么干的。這也是促使我去寫這篇文章的原因之一。 而目前的deent75,也允許用戶指定生成的結果文件是DjVu還是PDF,如果選擇PDF,就直接實現了圖像轉分層PDF。

5.2 反向轉換

在討論完DjVu轉PDF后,一個很自然的問題就是:這樣轉換出來的PDF,能不能再轉回DjVu?

我對這個問題的回答是:看你想怎么轉。最簡單的辦法當然是直接打印到DjVu虛擬打印機上,或者找一個現成的PDF2DjVu軟件,喜歡折騰的也可以先把PDF轉圖片,然后圖片轉DjVu。

不過既然前面說了半天數據格式轉換,那咱們的思維還是別太發散,還是按照同樣的思路:能不能從PDF文件數據流里抽取圖像數據流,及層次描述,然后盡量無損地轉換回DjVu?我的回答是:不一定。理由如下:

  • 對於PDF中的JBig2數據流,如果沒有半調圖像摻合在里面,則與DjVu的JB2數據流具有對應關系,可以無損轉回JB2數據流。不過我在PdfToy和UnicornViewer中實現這個過程的時候,碰到了與最初JB2轉JBig2一樣的問題:轉回來的文件長度要比原DjVu文件長度大。從對djvulibre源代碼的分析看,這同樣也是因為JB2中的“字典二次編碼”造成的,不過我實在沒有耐心深入研究,所以采取了一個偷懶的辦法:在“導出”界面中增加了一個“二次編碼”選項,如果該選項未選中,則用我自己的偷懶方法,即把JBig2中的數據取出來,直接轉換成JB2編碼,中間不需要全圖解碼成位圖,這個過程可以驗證是無損的;否則把全圖解碼成位圖,然后用minidjvu或djvulibre的cjb2, 按無損參數重新進行分割、聚類,再編碼成JB2,這樣出來的結果可能造成字典和頁面描述的改變,但全圖仍然是無損的,數據流長度也能變小一點。
  • 對於PDF中的JPEG 2000數據,我也沒辦法直接轉換成IW44,而且由於djvulibre中的IW44壓縮接口不支持指定壓縮率,所以即使解碼成位圖后重新壓縮,也很難保證文件長度不變。
  • 彩色文字方面,如果不重新處理,我也猜不出該用什么方法才能轉回去。

因此,我至今也只實現了把PDF中的JBig2導出為DjVu,但不敢去試PDF->DjVu,而且建議各位也別閑來無事轉着玩,不然哪天突然后悔了可沒地兒買葯去。

反向轉換的研究雖然進行得不徹底,不過也產生了其他的副產品:在研究過程中,我感覺未來采用JPEG 2000壓縮的PDF會增加,因此在UnicornViewer中專門加強了對這方面的支持,並且我名下所有與PDG相關的軟件,均開始支持“名為PDG實為JPEG 2000的文件”:如果PDF中的圖片實在轉不回DjVu,干脆導出成圖片看算了。

5.3 PDF瀏覽器限制

按照我前面說的方法和工具轉換出來的PDF采用了JBig2、JPEG 2000壓縮,前者要求Acrobat 5以上版本,后者要求Acrobat 6以上版本的瀏覽器才能正常顯示。好在現在主流的Acrobat版本最低也是7。其他常見的PDF瀏覽器中,PDF-XChange支持這兩種格式沒有問題,Foxit需要專門的插件,CajViewer則不支持。我自己的UnicornViewer沒有問題,在JPEG 2000方面還進行過專門強化,比Acrobat8的兼容性更好。


免責聲明!

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



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