2013-06-18 24 views
4

我正在嘗試創建一個Grails應用程序,它可以顯示TIFF文件和其他圖像的預覽。如何將TIFF ImageReader添加到在Grails中註冊的人

背景

圖像是從一個SOAP服務構造的,該服務給了我圖像的字節。在服務方法中,我使用byte [],從中構建一個ByteArrayInputStream,然後從中創建一個BufferedImage。

def inputStream = new ByteArrayInputStream(bytes) 
BufferedImage originalImage = ImageIO.read(inputStream) 
ImageIO.write(originalImage, 'png', response.outputStream) 

對於JPG,我可以很容易地將圖像作爲img標籤的src流式傳輸到瀏覽器。 TIFFs,但是,我需要將圖像轉換爲其他格式(最好是JPG或PNG),以使它們成爲標籤的src。

的問題

我知道I need JAI in order to read the TIFF files。 jai_core.jar,jai_codec.jar文件位於我的類路徑中。事實上,因爲我在Mac OSX上,它們會自動安裝。然而,當我運行Grails應用程序,並嘗試構建從SOAP服務接收的字節的TIFF圖像,我得到這個錯誤:

| Error 2013-06-18 15:23:38,135 [http-bio-8080-exec-10] ERROR errors.GrailsExceptionResolver - IllegalArgumentException occurred when processing request: [GET] /BDMPlugin/BDMPlugin/displayImageFromRef - parameters: 
pageRef: 28:22072FBCA0A8889D9C041D76A588BCF4DCB40376A23B5FD5C301378C8E66EB9F4933A5DFCA46365F927D9E91B337B6E1E980FB4406644801 
type: TIFF 
im == null!. Stacktrace follows: 
Message: im == null! 
    Line | Method 
->> 1457 | write    in javax.imageio.ImageIO 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
| 1571 | write    in  '' 
|  28 | writeImageToResponse in edu.missouristate.bdmplugin.ImageService 
|  44 | bytesToPng   in  '' 
|  39 | displayImageFromRef in edu.missouristate.bdmplugin.BDMPluginController 
| 895 | runTask    in java.util.concurrent.ThreadPoolExecutor$Worker 
| 918 | run . . . . . . . . in  '' 
^ 680 | run     in java.lang.Thread 

我嘗試以下script找出安裝了哪些圖像閱讀器:

IIORegistry reg = IIORegistry.getDefaultInstance(); 
Iterator spIt = reg.getServiceProviders(ImageReaderSpi.class, false); 
spIt.each(){ 
println it.getVendorName() << " | " << it.getVersion() << " | "<< it.getDescription() ; 
} 

此輸出以下:

Sun Microsystems, Inc. | 1.0 | Standard BMP Image Reader 
Sun Microsystems, Inc. | 1.0 | Standard GIF image reader 
Sun Microsystems, Inc. | 1.0 | Standard WBMP Image Reader 
Sun Microsystems, Inc. | 1.0 | Standard PNG image reader 
Sun Microsystems, Inc. | 0.5 | Standard JPEG Image Reader 

但是,如果我跑,在Groovy的控制檯相同的Groovy腳本,我得到這個輸出:

Sun Microsystems, Inc. | 0.5 | Standard JPEG Image Reader 
Sun Microsystems, Inc. | 1.0 | Standard BMP Image Reader 
Sun Microsystems, Inc. | 1.0 | Standard WBMP Image Reader 
Sun Microsystems, Inc. | 1.0 | Standard PNG image reader 
Sun Microsystems, Inc. | 1.0 | Standard GIF image reader 
Apple computer Inc. | 1.0 | Standard TIFF image reader 

同一套閱讀器,但它也包括蘋果的TIFF閱讀器。爲什麼GroovyConsole能夠找到它而不是我的Grails環境,即使它們都使用相同的JRE?有沒有一種方法可以通過從導入com.sun.media.jaicom.sun.media.imageio.plugins.tiff進口的某些導入手動添加TIFF閱讀器?

我嘗試添加了TIFFImageReaderSpi的手工登記到我的服務方法:

import com.sun.imageio.plugins.tiff.TIFFImageReaderSpi 
... 
IIORegistry reg = IIORegistry.getDefaultInstance() 
reg.registerServiceProvider(new TIFFImageReaderSpi()) 

的originalImage變量仍然回來空。

+0

我有理由確定(至少部分)問題是我需要註冊一個可以處理TIFF文件的ImageWriter。然而,在我的JAI課程中似乎沒有這樣的課程。在尋找它的時候,JAI似乎已經有點像圖書館一樣不存在了。如果有人在Grails中取得成功,我可以選擇將TIFF轉換爲更友好的圖像。 – jonnybot

+0

+1格式良好的問題。 – dmahapatro

+0

@jonnybot ImageIO使用服務查找機制。通常不需要手動註冊'Spi's,只需將相應的JAR放在classpath上即可。此外,您不需要支持TIFF的ImageWriter,因爲您只需編寫JPEG和PNG。 – haraldK

回答

5

所以似乎有一些問題層出不窮。

首先,import com.sun.imageio.plugins.tiff.TIFFImageReaderSpi聲明導入了Apple TIFF閱讀器,這顯然不符合閱讀我的TIFF的工作。

真的需要的是import com.sun.media.imageioimpl.plugins.tiff.TIFFImageReaderSpi,但這給我帶來了幾個不同的錯誤;別擔心,我可以修復它們。 :)

首先,導入沒有解決。爲了獲得com.sun.media.imageioimpl軟件包,我從https://github.com/stain/jai-imageio-core獲得了捆綁JAI的源代碼。我將它導入到Eclipse中,然後使用Eclipse的導出工具構建了一個JAR。這我放在我的項目的lib文件夾,但導入仍然沒有解決。我必須手動將該jar添加到我的項目的類路徑中,然後導入才能解決。

其次,當我跑的應用程序,我會得到這個錯誤:

| Error 2013-06-19 11:15:27,665 [http-bio-8080-exec-3] ERROR errors.GrailsExceptionResolver - IllegalArgumentException occurred when processing request: [GET] /pluginproject/Controller/action - parameters: 
vendorName == null!. Stacktrace follows: 
Message: vendorName == null! 
    Line | Method 
->> 59 | <init>    in javax.imageio.spi.IIOServiceProvider 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
| 214 | <init>    in javax.imageio.spi.ImageReaderWriterSpi 
| 192 | <init> . . . . . . in javax.imageio.spi.ImageReaderSpi 
| 88 | <init>    in com.sun.media.imageioimpl.plugins.tiff.TIFFImageReaderSpi 
| 31 | bytesToPng . . . . in edu.mystateu.pluginproject.ImageService 

VENDORNAME == NULL?幸運的是,我發現這個question/answer

爲jai-imageio-core創建jar文件時,我不得不手動指定清單文件的位置,而不是讓Eclipse生成一個新的空白文件。清單文件位於/jai-imageio-core/src/main/resources/META-INF/MANIFEST.MF中,一旦我指定使用該文件,導入的lib就會解析並讀取我的映像。

最後,服務方法的代碼非常好。我只需要將JAI正確導入到我的項目中。 @haraldK非常感謝,他的反饋讓我走上了正軌。

2

一種解決方案可以工作,是創建一個文件

/META-INF/services/ImageReaderSpi 

包含一行

com.sun.imageio.plugins.tiff.TIFFImageReaderSpi 

,並將其放置在classpath。

這應該確保提供商已正確註冊。

但是請注意,Apple提供的TIFFImageReader與JAI中的不一樣,即使包/類名稱相同。

如果您想使用JAI TIFF ImageReader,您將需要jai-imageio.jar。正如你所指出的那樣,這個項目目前正在被Oracle拋在一邊。

如果因爲任何原因不喜歡使用JAI,我已經爲GitHub上的ImageIO創建了一個純Java TIFF插件:Twelvemonkeys TIFF plugin。該插件可用於商業友好的開源許可證(BSD)。

+0

如果你的TIFF插件有與之相關的許可證,它會讓我的惡霸們非常高興。 :) – jonnybot

+1

@jonnybot聽起來很合理.. :-)只是推了一個license.txt回購。儘管如此,所有的12個猴子都在BSD許可下。 – haraldK

2

我有同樣的問題,同時可以手動註冊單個插件,也有註冊這這可能是一點點清潔類路徑中的所有可用的插件的方法:

ImageIO.scanForPlugins(); 
相關問題