【问题标题】:Read byte array into buffered image WITHOUT ImageIO在没有 ImageIO 的情况下将字节数组读入缓冲图像
【发布时间】:2014-07-11 01:17:09
【问题描述】:

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

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。

这是堆栈跟踪:

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 来做到这一点吗?

提前致谢!

【问题讨论】:

  • 该图像在上传或下载过程中可能发生了问题,但我的 Java(版本 1.7.0_51)读取该图像时没有错误。
  • @ScaryWombat 这无关。这是由损坏/非标准 ICC 配置文件引起的 JPEG 解码问题。

标签: java jpeg javax.imageio jai


【解决方案1】:

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

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

更新:我刚刚尝试读取图像,Java 版本 1.7.0_60 可以读取图像,但是颜色略有不同(它变成紫色,就像在 Chrome 中一样),因为忽略了 ICC 配置文件。这对你来说可能已经足够好了。如果没有,请使用 TwelveMonkeys JPEG 插件。 :-)

【讨论】:

    猜你喜欢
    • 2018-02-28
    • 2018-07-21
    • 1970-01-01
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-27
    相关资源
    最近更新 更多