How to add TIFF ImageReader to registered in Grails

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.

+4
source share
3 answers

So the problem is with multiple layers.

First, the import com.sun.imageio.plugins.tiff.TIFFImageReaderSpi statement imported an Apple TIFF reader, which apparently did not match my TIFF reading job.

I really needed to import com.sun.media.imageioimpl.plugins.tiff.TIFFImageReaderSpi , but this showed me a couple of different errors; don't worry, I was able to fix them. :)

Firstly, imports were not permitted. To get the com.sun.media.imageioimpl package, I got the source for the associated JAI from https://github.com/stain/jai-imageio-core . I imported this into Eclipse and then created a JAR using the Eclipse Export tool. I put this in my lib project folder, but the import was still not resolved. I had to manually add this jar to my project path, and then import will be allowed.

Secondly, when I started the application, I would get this error:

 | 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? Fortunately, I found this question / answer .

When creating the jar file for jai-imageio-core, I had to manually specify the location of the manifest file, instead of letting Eclipse generate a new empty one. The manifest file was in the file / jai -imageio-core / src / main / resources / META-INF / MANIFEST.MF, and as soon as I indicated to use it, the imported lib allowed and read my image.

In the end, the service method code was excellent. I just needed to import JAI correctly into my project. Thanks a lot @haraldK, whose feedback led me on the right track.

+5
source

One solution that may work is to create a file

 /META-INF/services/ImageReaderSpi 

contains one line

 com.sun.imageio.plugins.tiff.TIFFImageReaderSpi 

and put it on the classpath.

This should ensure that the provider is correctly registered.

However, keep in mind that Apple provided the TIFFImageReader not the same as the JAI, even if the package / class names are the same.

If you want to use the JAI TIFF ImageReader, you will need jai-imageio.jar. Currently, the project, as you noted, is left in the uncertainty of Oracle.

If you don’t like using JAI for any reason, I created a clean Java TIFF plugin for ImageIO, available on GitHub: Twelvemonkeys TIFF plugin . The plugin is available under an open source developer (BSD) license.

+2
source

I had the same problem, and although you can manually register individual plugins, there is also a way to register all the plugins available in the classpath, which is probably a bit cleaner:

 ImageIO.scanForPlugins(); 
+2
source

Source: https://habr.com/ru/post/1486929/


All Articles