Исключение исключительного аргумента ImageIO.read - растровые полосы/компоненты цветового пространства?

Извиняюсь за несколько смутное название, я не могу понять, какие ключевые слова здесь. Настройка довольно проста, я открываю изображение с помощью

ImageIO.read(new File(filename));

Это работает для большинства файлов, однако для одного я получаю IllegalArgumentException with the detail: "numbers of source Raster bands and source color space components do not match". Это изображение было получено с помощью wget на корректном URL-адресе Flickr, и я использовал другие изображения, полученные таким образом, поэтому метод получения изображений кажется в принципе понятным. Я не уверен, что вызывает исключение.

Обходной путь был бы более чем приемлемым - я не суетился с использованием ImageIO, в частности, и изображение выглядит отлично визуально. Мне просто нужно, чтобы его читали без использования Java!

Вот изображение, о котором идет речь, в случае его использования:

enter image description here

Ответ 1

Итак, у меня была такая же проблема, и я обнаружил, что изображение было серым, и что реализация ImageIO.read по умолчанию не выяснила этого, потому что метаданные изображения были не такими ожидаемыми. Я написал работу, которая повторяет загрузку как "BufferedImage.TYPE_BYTE_GRAY", если она не справляется с основной нагрузкой.

            Iterator<ImageReader> iter = ImageIO.getImageReaders(stream);

        Exception lastException = null;
        while (iter.hasNext()) {
            ImageReader reader = null;
            try {
                reader = (ImageReader)iter.next();
                ImageReadParam param = reader.getDefaultReadParam();
                reader.setInput(stream, true, true);
                Iterator<ImageTypeSpecifier> imageTypes = reader.getImageTypes(0);
                while (imageTypes.hasNext()) {
                    ImageTypeSpecifier imageTypeSpecifier = imageTypes.next();
                    int bufferedImageType = imageTypeSpecifier.getBufferedImageType();
                    if (bufferedImageType == BufferedImage.TYPE_BYTE_GRAY) {
                        param.setDestinationType(imageTypeSpecifier);
                        break;
                    }
                }
                bufferedImage = reader.read(0, param);
                if (null != bufferedImage) break;
            } catch (Exception e) {
                lastException = e;
            } finally {
                if (null != reader) reader.dispose();               
            }
        }
        // If you don't have an image at the end of all readers
        if (null == bufferedImage) {
            if (null != lastException) {
                throw lastException;
            }
        }

Ответ 2

Сообщение об ошибке является информативным и указывает, что количество растровых полос, как указано в цветовом профиле ICC, кажется неправильным. Я использовал ImageMagick, чтобы удалить профиль ICC с изображения. ImageIO впоследствии не имеет проблем с чтением изображений (~ 1k плохих изображений). Надеюсь, что это поможет.

Ответ 3

Это изображение можно прочитать с помощью twelvemonkeys ImageIO, который является более надежной и прощающей заменой для исходного ImageIO, предоставленного JRE.

См. https://github.com/haraldk/TwelveMonkeys/

Я нашел это решение в PDF-окне Jira https://issues.apache.org/jira/browse/PDFBOX-3637

Чтобы использовать twelvemonkeys, достаточно добавить его как зависимость от maven. Затем он регистрируется перед процессором изображения по умолчанию.

<dependency>
    <groupId>com.twelvemonkeys.imageio</groupId>
    <artifactId>imageio-jpeg</artifactId>
    <version>3.3.2</version> <!-- Alternatively, build your own version -->
</dependency>