4

我有一个奇怪的 JPEG 图像文件 ImageIO.read() 无法加载:

ImageIO.read(new URL("http://nocturne.wmw.cc/a.jpg"));

有任何想法吗?

Exception in thread "main" javax.imageio.IIOException: Unsupported Image Type
    at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:995)
    at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:966)
    at javax.imageio.ImageIO.read(ImageIO.java:1448)
    at javax.imageio.ImageIO.read(ImageIO.java:1400)
    at Main.main(Main.java:23)

图片网址

4

1 回答 1

5

好吧...我花了一段时间才发现这个问题...问题出在图像本身,它有一个 CMYK 颜色配置文件(即 Coated FOGRA27),混淆了 java 中的 JPEG 阅读库。

在 Photoshop 中打开图像会生成 CMYK 颜色模式的图像(至少对我而言),这似乎不受 java 支持。将颜色模式更改为 RGB 并使用 sRGB 颜色配置文件保存允许 ImageIO 库成功读取图像。

ImageIO 库仅实现可读颜色配置文件的子集,并且不处理没有任何配置文件的图像。

进一步阅读 JPEGImageReader 源代码得到以下代码:

switch (colorSpaceCode) {
    case JPEG.JCS_GRAYSCALE:
        list.add(raw);
        list.add(getImageType(JPEG.JCS_RGB));
        break;
    case JPEG.JCS_RGB:
        list.add(raw);
        list.add(getImageType(JPEG.JCS_GRAYSCALE));
        list.add(getImageType(JPEG.JCS_YCC));
        break;
    case JPEG.JCS_RGBA:
        list.add(raw);
        break;
    case JPEG.JCS_YCC:
        if (raw != null) {  // Might be null if PYCC.pf not installed
            list.add(raw);
            list.add(getImageType(JPEG.JCS_RGB));
        }
        break;
    case JPEG.JCS_YCCA:
        if (raw != null) {  // Might be null if PYCC.pf not installed
            list.add(raw);
        }
        break;
    case JPEG.JCS_YCbCr:
        // As there is no YCbCr ColorSpace, we can't support
        // the raw type.

        // due to 4705399, use RGB as default in order to avoid
        // slowing down of drawing operations with result image.
        list.add(getImageType(JPEG.JCS_RGB));

        if (iccCS != null) {
            list.add(new ImageTypeProducer() {
                protected ImageTypeSpecifier produce() {
                    return ImageTypeSpecifier.createInterleaved
                     (iccCS,
                      JPEG.bOffsRGB,  // Assume it's for RGB
                      DataBuffer.TYPE_BYTE,
                      false,
                      false);
                }
            });

        }

        list.add(getImageType(JPEG.JCS_GRAYSCALE));
        list.add(getImageType(JPEG.JCS_YCC));
        break;
    case JPEG.JCS_YCbCrA:  // Default is to convert to RGBA
        // As there is no YCbCr ColorSpace, we can't support
        // the raw type.
        list.add(getImageType(JPEG.JCS_RGBA));
        break;
}

异常的来源:

Iterator imageTypes = getImageTypes(imageIndex);
if (imageTypes.hasNext() == false) {
    throw new IIOException("Unsupported Image Type");
}

如您所见,当 JPEG 图像的颜色配置文件未在 switch 语句中列出时,不会将任何内容添加到“列表”变量中,该变量最终会传递给第二段代码中的特定迭代器。对于空列表,Iterator.hasNext() 方法返回 false,抛出异常。

于 2013-10-21T16:53:01.200 回答