在没有ImageIO的情况下将字节数组读入缓冲的图像

在没有ImageIO的情况下将字节数组读入缓冲的图像

本文介绍了在没有ImageIO的情况下将字节数组读入缓冲的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用ImageIO将字节数组转换为BufferedImage的代码.

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
}

但是我发现对于某些jpeg图像,每次都会抛出CMMException.

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

这是堆栈跟踪:

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)

这是引起麻烦的照片

我在Google上搜索了一个解决方案,并发现了一个确认该问题的帖子,并建议在ImageIO失败的情况下使用JAI.但是我对此感到怀疑,因为该帖子是4年前发布的,而且我似乎找不到太多有关JAI的信息,这使我相信这不是理想的解决方案.没有ImageIO或JAI,还有其他方法可以将字节数组转换为缓冲的图像吗?如果今天JAI仍然是可靠的解决方案,那么有人可以教我如何使用JAI做到这一点吗?

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?

提前谢谢!

推荐答案

首先,您可以使用我的TwelveMonkeys 用于ImageIO的JPEG插件,它将阅读此JPEG .无需更改您的代码.据我所知,问题在于它包含使用过时或损坏的ICC配置文件格式的Corbis RGB ICC颜色配置文件.我的阅读器将在运行时修补ICC配置文件,并很好地读取图像.

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.

此外,堆栈跟踪中的LCMS引用表明您使用的是OpenJDK还是Java8.至少对于Java 8,有一个开关-Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider重新启用Kodak CMS(在Java 8之前的所有Sun/Oracle JRE中使用),在Java 8中选择LittleCMS作为默认值之后,这些颜色管理系统处理ICC配置文件的方式略有不同,因此设置在某些情况下,此开关可能会有所帮助.

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.

更新:我只是尝试读取图像,而Java版本1.7.0_60可以读取图像,但是颜色略有变化(像在Chrome中一样呈紫色),因为忽略了ICC配置文件.这对您可能已经足够了.如果不是,请使用TwelveMonkeys JPEG插件. :-)

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

这篇关于在没有ImageIO的情况下将字节数组读入缓冲的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 06:24