I am trying to create a Grails application that can display previews of TIFF files and other images.
Background
Images are built from a SOAP service that gives me image bytes. In the service method, I take the byte [], create a ByteArrayInputStream from it, and then create a BufferedImage from this.
def inputStream = new ByteArrayInputStream(bytes) BufferedImage originalImage = ImageIO.read(inputStream) ImageIO.write(originalImage, 'png', response.outputStream)
For JPG, I can easily transfer images to the browser in a way like src of the img tag. TIFF, however, I will need to convert the images to another format (preferably JPG or PNG) to make them an src tag.
Problem
I know that I need JAI to read TIFF files . Files jai_core.jar, jai_codec.jar are in my classpath. In fact, since I'm on Mac OSX, they install automatically. However, when I start the grails application and it tries to create a TIFF image from bytes received from the SOAP service, I get this error:
| 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
I tried the following script to find out which image readers were installed:
IIORegistry reg = IIORegistry.getDefaultInstance(); Iterator spIt = reg.getServiceProviders(ImageReaderSpi.class, false); spIt.each(){ println it.getVendorName() << " | " << it.getVersion() << " | "<< it.getDescription() ; }
Outputs the following:
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
However, if I run the same Groovy script in the Groovy console, I get this output:
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
The same set of readers, but also includes an Apple TIFF reader. Why can GroovyConsole find it and not my Grails environment, although they both use the same JRE? Is there a way that I can manually add a TIFF reader through some import from the com.sun.media.jai or com.sun.media.imageio.plugins.tiff import?
I tried adding the manual TIFFImageReaderSpi registration to my service method:
import com.sun.imageio.plugins.tiff.TIFFImageReaderSpi ... IIORegistry reg = IIORegistry.getDefaultInstance() reg.registerServiceProvider(new TIFFImageReaderSpi())
The original -Image variable still returns null.