ImageIO在读取期间抛出60x45,0.5MB的JPEG图像文件的IIOException

时间:2013-10-21 15:10:35

标签: java image metadata

我有一个奇怪的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)

imageurl

1 个答案:

答案 0 :(得分:4)

好的......我花了一段时间才发现这个问题......问题在于图像本身,它有一个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");
}

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