javajpegjava-2djavax.imageioresize-image

Is there a 100% Java alternative to ImageIO for reading JPEG files?


We are using Java2D to resize photos uploaded to our website, but we run into an issue (a seemingly old one, cf.: http://forums.sun.com/thread.jspa?threadID=5425569) - a few particular JPEGs raise a CMMException when we try to ImageIO.read() an InputStream containing their binary data:

java.awt.color.CMMException: Invalid image format
 at sun.awt.color.CMM.checkStatus(CMM.java:131)
 at sun.awt.color.ICC_Transform.<init>(ICC_Transform.java:89)
 at java.awt.image.ColorConvertOp.filter(ColorConvertOp.java:516)
 at com.sun.imageio.plugins.jpeg.JPEGImageReader.acceptPixels(JPEGImageReader.java:1114)
 at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImage(Native Method)
 at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:1082)
 at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:897)
 at javax.imageio.ImageIO.read(ImageIO.java:1422)
 at javax.imageio.ImageIO.read(ImageIO.java:1326)
    ...

(snipped the remainder of the stack trace, which is our ImageIO.read() call, servlet code and such)

We narrowed it down to photos taken on specific cameras, and I selected a photo that triggers this error: http://img214.imageshack.us/img214/5121/estacaosp.jpg. We noticed that this only happens with Sun's JVM (on Linux and Mac, just tested it on 1.6.0_20) - a test machine with OpenJDK reads the same photos without a hitch, possibly due to a different implementation of the JPEG reader.

Unfortunately, we are unable to switch JVMs in production, nor to use native-dependent solutions such as ImageMagick ( http://www.imagemagick.org/ ).

Considering that, my question is: Does a replacement for ImageIOs JPEG reader which can handle photos such as the linked one exist? If not, is there another 100% pure Java photo resizing solution which we can use?

Thank you!


Solution

  • One possibly useful library for you could be the Java Advanced Imaging Library (JAI)

    Using this library can be quite a bit more complicated than using ImageIO but in a quick test I just ran, it did open and display the problem image file you linked.

    public static void main(String[] args) {
            RenderedImage image = JAI.create("fileload", "estacaosp.jpg");
    
            float scale=(float) 0.5;
    
            ParameterBlock pb = new ParameterBlock();
            pb.addSource(image);
    
            pb.add(scale);
            pb.add(scale);
            pb.add(1.0F);
            pb.add(1.0F);
    
            pb.add(new InterpolationNearest() );// ;InterpolationBilinear());
            image = JAI.create("scale", pb);
    
            // Create an instance of DisplayJAI.
            DisplayJAI srcdj = new DisplayJAI(image);
    
            JScrollPane srcScrollPaneImage = new JScrollPane(srcdj);
    
    // Use a label to display the image
            JFrame frame = new JFrame();
    
            frame.getContentPane().add(srcScrollPaneImage, BorderLayout.CENTER);
            frame.pack();
            frame.setVisible(true);
        }
    

    After running this code the image seems to load fine. It is then resized by 50% using the ParamaterBlock

    And finally if you wish to save the file you can just call :

    String filename2 = new String ("tofile.jpg");
      String format = new String ("JPEG");
      RenderedOp op = JAI.create ("filestore", image, filename2, format);
    

    I hope this helps you out. Best of luck.