4

I have a weird JPEG image file that ImageIO.read() fails to load:

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

Any ideas?

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

4

1 に答える 1

5

わかりました...これの問題を見つけるのにしばらく時間がかかりました...問題は画像自体にあり、CMYKカラープロファイル(つまりCoated FOGRA27)があり、JavaのJPEG読み取りライブラリを混乱させます。

Photoshop で画像を開くと、Java ではサポートされていないように見える CMYK カラー モードの画像が生成されます (少なくとも私にとっては)。カラー モードを 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 ステートメントにリストされていない場合、'list' 変数には何も追加されず、最終的にコードの 2 番目のセグメントで特定の反復子に渡されます。リストが空の場合、Iterator.hasNext() メソッドは false を返し、例外をスローします。

于 2013-10-21T16:53:01.200 に答える