Read byte array into buffered image WITHOUT ImageIO
Asked Answered
B

1

1

I have a code that turns a byte array into BufferedImage using ImageIO.

public void readImage(byte[] imageBytes) {
    ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes);
    BufferedImage bufferedImage = null;

    try {
        bufferedImage = ImageIO.read(inputStream);
    } catch (Exception e) {
        e.printStackTrace();
    }
    // do something with bufferedImage
}

But I found that for certain jpeg images, it throws a CMMException, every time.

Here's the stack trace:

java.awt.color.CMMException: Cannot get color transform
        at sun.java2d.cmm.lcms.LCMS.createNativeTransform(Native Method)
        at sun.java2d.cmm.lcms.LCMSTransform.<init>(LCMSTransform.java:103)
        at sun.java2d.cmm.lcms.LCMS.createTransform(LCMS.java:75)
        at java.awt.image.ColorConvertOp.filter(ColorConvertOp.java:552)
        at com.sun.imageio.plugins.jpeg.JPEGImageReader.acceptPixels(JPEGImageReader.java:1251)
        at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImage(Native Method)
        at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:1219)
        at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:1022)
        at javax.imageio.ImageIO.read(ImageIO.java:1438)
        at javax.imageio.ImageIO.read(ImageIO.java:1342)

And here's the photo that's causing troubleenter image description here

I searched on Google for a solution, and found a post acknowledging the problem and recommending to use JAI for cases where ImageIO fails. But I'm having doubts, as the post was from 4 years ago, and I can't seem to find much information about JAI, leading me to believe that that's not the ideal solution. Is there any other way to convert byte array into buffered image without ImageIO or JAI? And if JAI is still a solid solution today, could someone show me how to do that using JAI?

Thanks in advance!

Bronco answered 11/7, 2014 at 1:17 Comment(3)
possible duplicate of Convert InputStream(Image) to ByteArrayInputStreamInfective
Something may have happened to that image during upload or download, but my Java (version 1.7.0_51) reads that image without errors.Immaculate
@ScaryWombat That's unrelated. This is a JPEG decoding issue caused by a broken/non-standard ICC profile.Tirzah
T
2

First of all, you can use my TwelveMonkeys JPEG plugin for ImageIO, it will read this JPEG. No need to change your code. From what I remember, the issue was that it contains a Corbis RGB ICC color profile, using an outdated or broken ICC profile format. My reader will patch the ICC profile at runtime, and read the image just fine.

Further, the LCMS references in the stack trace indicates you are either on OpenJDK or, Java 8. For Java 8 at least, there is a switch -Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider to re-enable the Kodak CMS (used in all Sun/Oracle JREs pre Java 8), after LittleCMS was chosen as the default from Java 8. There are minor differences in how these color management systems handle ICC profiles, so setting this switch might help in certain cases.

Update: I just tried to read the image, and Java version 1.7.0_60 could read the image, however the colors are slightly off (it gets a purple tint, like in Chrome), because the ICC profile is ignored. This might be good enough for you. If not, use the TwelveMonkeys JPEG plugin. :-)

Tirzah answered 11/7, 2014 at 7:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.