8

带有此文件的 ImageIO.read(imagePath) 给出了 CMMException,为什么 Java 不能处理这个看似有效的文件http://www.jthink.net/jaikoz/scratch/front.jpg

java.awt.color.CMMException: Invalid image format
    at sun.awt.color.CMM.checkStatus(Unknown Source)
    at sun.awt.color.ICC_Transform.<init>(Unknown Source)
    at java.awt.image.ColorConvertOp.filter(Unknown Source)
    at com.sun.imageio.plugins.jpeg.JPEGImageReader.acceptPixels(Unknown Source)
    at com.sun.imageio.plugins.jpeg.JPEGImageReader.readImage(Native Method)
    at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(Unknown Source)
    at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(Unknown Source)
    at javax.imageio.ImageIO.read(Unknown Source)
    at javax.imageio.ImageIO.read(Unknown Source)
4

3 回答 3

15

我想我明白了你的问题。我检查了您链接的图像(http://www.jthink.net/jaikoz/scratch/front.jpg)。由于 Exif 和 JFIF 标准。

当您执行类似的操作时ImageIO.read('some file'),它会调用默认的 sun jpeg 实现com.sun.imageio.plugins.jpeg.JPEGImageReader。以前在加载 JFIF 文件时遇到问题BUG 6488904(检查最后的评论)。

根据规范,Exif 和 JFIF 都要求它们各自的应用程序标记段必须是 SOI(APP1 和 APP0)之后的第一个,因此实际上不可能按照规范来使 JPEG 文件同时符合这两个标准。

虽然很久以前就有报道

解决方法是使用 JAI 库 ( https://jai.dev.java.net/binary-builds.html#Release_builds )。我正在使用Java(无本机加速)版本。

SeekableStream seekableStream =  new FileSeekableStream(new File("front.jpg"));
ParameterBlock pb = new ParameterBlock();
pb.add(seekableStream);

BufferedImage image = JAI.create("jpeg", pb).getAsBufferedImage();

希望这会有所帮助。

于 2010-12-17T16:45:05.490 回答
4

顺便说一句,这个问题在 JDK8 中得到了修复(注意http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7064516底部的提交)。我已经确认JDK8 的预发布版本可以正确加载 JDK7 失败的映像,如上所述。

于 2013-10-09T21:18:35.177 回答
2

旧帖子,但供将来参考:

受此问题和此处找到的链接的启发,我为 ImageIO 编写了一个 JPEGImageReader 插件,该插件支持具有这些“坏”ICC 颜色配置文件的 JPEG 图像(“问题”是 ICC 配置文件中的渲染意图与 Java 的 ColorConvertOp 不兼容)。它是纯 Java,不需要 JAI。源代码可在以下位置免费获得:

https://github.com/haraldk/TwelveMonkeys/tree/master/imageio/imageio-jpeg

于 2013-04-22T14:07:58.630 回答