一、問題背景
我正在建立一個java項目,使用pdfBox從PDF中獲取圖像。因為我在使用 tika-app 實現其他功能,所以我決定使用 tika-app-1.20.jar 中的pdfBox。
我曾經嘗試過包含 jai-imageio-core-1.3.1.jar,因為Tika-app 已經與這個jar捆綁在一起。我試過單獨使用 tika-app jar。
拋出錯誤的這條代碼:
PDXObject object=resources.getXObject(cosName);
錯誤的日志跟蹤:
org.apache.pdfbox.filter.MissingImageReaderException: Cannot read JPEG2000 image:
Java Advanced Imaging (JAI) Image I/O Tools are not installed at org.apache.pdfbox.filter.Filter.findImageReader(Filter.java:163) at org.apache.pdfbox.filter.JPXFilter.readJPX(JPXFilter.java:115) at org.apache.pdfbox.filter.JPXFilter.decode(JPXFilter.java:64) at org.apache.pdfbox.cos.COSInputStream.create(COSInputStream.java:77) at org.apache.pdfbox.cos.COSStream.createInputStream(COSStream.java:175) at org.apache.pdfbox.cos.COSStream.createInputStream(COSStream.java:163) at org.apache.pdfbox.pdmodel.common.PDStream.createInputStream(PDStream.java:236) at org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject.<init>(PDImageXObject.java:140) at org.apache.pdfbox.pdmodel.graphics.PDXObject.createXObject(PDXObject.java:70) at org.apache.pdfbox.pdmodel.PDResources.getXObject(PDResources.java:426)
但我很確定我在tika有jai imageio內核,當我運行代碼時,它是不可見的。
解決方案:
1、It happens that it requires an additional jar known as jai-imageio-jpeg2000 to support jp2k images. 說的是:它需要一個額外的jai-imageio-jpeg2000 jar來支持jp2k圖像。
2、事實上,我也偶然發現了這個錯誤,但這里的PDFBox文檔中提到了這一點。您需要將以下依賴項添加到pom.xml中:
<dependency>
<groupId>com.github.jai-imageio</groupId>
<artifactId>jai-imageio-core</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>com.github.jai-imageio</groupId>
<artifactId>jai-imageio-jpeg2000</artifactId>
<version>1.3.0</version>
</dependency>
<!-- Optional for you ; just to avoid the same error with JBIG2 images -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>jbig2-imageio</artifactId>
<version>3.0.3</version>
</dependency>
為了避免JBIG2圖像出現同樣的錯誤,可以加上后面那個依賴。
如果您正在使用Gradle,則這樣加上依賴:
dependencies {
implementation 'com.github.jai-imageio:jai-imageio-core:1.4.0'
implementation 'com.github.jai-imageio:jai-imageio-jpeg2000:1.3.0'
// Optional for you ; just to avoid the same error with JBIG2 images
implementation 'org.apache.pdfbox:jbig2-imageio:3.0.3'
}
二、項目實例場景
1、問題場景:
在項目中文檔轉換 - PDF轉圖片功能出現了一個BUG(使用pdfbox2.0.2),原PDF文件里面很多圖片元素,在轉換成圖片以后就消失不見了。這還了得,趕緊查日志,發現產生大量報錯:
ERROR o.a.p.contentstream.PDFStreamEngine 890 - Cannot read JPEG2000 image: Java Advanced Imaging (JAI) Image I/O Tools are not installed
這說的意思就是缺少啥 I/O 工具,不能讀取 JPEG2000 格式的圖片,問題應該就出在這里了。
2、問題原因:pdf 文件中可能包含的掃描件是JPEG2000格式的圖片,這樣pdfbox在轉換的過程中需要JAI的支持。
3、解決方案:加上相關依賴
國外stackoverflow:https://stackoverflow.com/questions/42169154/pdfbox1-8-12-convert-pdf-to-white-page-image,最后一條不起眼的小回復給了啟發,加上了依賴
4、對比:
添加依賴前 - 圖片丟失
添加依賴后 - 圖片展示
三、JPEG 與 JPEG2000 介紹了解
1、背景介紹:
JPEG 全名為 Joint Photographic Experts Group,它是一個在國際標准組織(ISO)下從事靜態圖像壓縮標准制定的委員會。它制定出了第一套國標靜態圖像壓縮標准:ISO 10918-1 就是我們俗稱的 JPEG 了。由於JPEG優良的品質,使得它在短短的幾年內就獲得極大的成功,目前網站上百分之八十的圖像都是采用JPEG的壓縮標准。
然而,隨著多媒體應用領域的激增,傳統JPEG壓縮技術已無法滿足人們對多媒體圖像資料的要求。因此,更高壓縮率以及更多新功能的新一代靜態圖像壓縮技術 JPEG 2000 就誕生了。JPEG 2000 正式名稱為 “ISO 15444” ,同樣是由JPEG 組織負責制定。
2、基本概念
JPEG 2000是基於小波變換的圖像壓縮標准,由Joint Photographic Experts Group組織創建和維護。JPEG 2000通常被認為是未來取代JPEG(基於離散余弦變換)的下一代圖像壓縮標准。JPEG 2000文件的副檔名通常為.jp2,MIME類型是image/jp2。
JPEG2000的壓縮比更高,而且不會產生原先的基於離散餘弦變換的JPEG標准產生的塊狀模糊瑕疵。
JPEG2000同時支持有損壓縮和無損壓縮。
另外,JPEG2000也支持更復雜的漸進式顯示和下載。
由於JPEG2000在無損壓縮下仍然能有比較好的壓縮率,所以JPEG2000在圖像品質要求比較高的醫學圖像的分析和處理中已經有了一定程度的廣泛應用。
3、JPEG2000 原理
JPEG 2000 與傳統 JPEG 最大的不同,在於它放棄了 JPEG 所采用的以離散餘弦轉換為主的區塊編碼方式,而改采以小波轉換為主的多解析編碼方式。
小波轉換的主要目的是要將圖像的頻率成分抽取出來。簡單原理圖可以參考下圖。
4、JPEG2000 優點
(1)JPEG2000 作為JPEG升級版,高壓縮(低碼率)是其目標,其壓縮率比 JPEG 高約 30% 左右。
(2)JPEG2000 同時支持有損和無損壓縮,而 JPEG 只能支持有損壓縮。因此它適合保存重要圖片。
(3)JPEG2000 能實現漸進傳輸,這是JPEG2000的一個極其重要的特征。這也就是我們對 GIF 格式圖像常說的“漸現”特性。它先傳輸圖像的輪廓,然后逐步傳輸數據,不斷提高圖像質量,讓圖象由朦朧到清晰顯示,而不必是像現在的 JPEG 一樣,由上到下慢慢顯示。
(4)JPEG2000 支持所謂的“感興趣區域”特性,你可以任意指定圖像上你感興趣區域的壓縮質量,還可以選擇指定的部份先解壓縮。這樣我們就可以很方便的突出重點了。
5、JPEG2000版權專利問題
JPEG2000 存在版權和專利的風險。這也許是目前JPEG2000技術沒有得到廣泛應用的原因之一。
JPEG2000標准本身是沒有授權費用,但是,因為編碼的核心部分的各種演算法被大量注冊專利,所以一般認為,不太可能避開這些專利費用開發出免授權費的商用編碼器。