Read byte array into buffered image WITHOUT ImageIO

删除回忆录丶 提交于 2020-01-15 12:16:07

问题


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 trouble

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!


回答1:


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. :-)



来源:https://stackoverflow.com/questions/24688780/read-byte-array-into-buffered-image-without-imageio

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!