Почему загрузка этого jpg с использованием JavaIO дает CMMException? - PullRequest
8 голосов
/ 17 декабря 2010

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)

Ответы [ 3 ]

15 голосов
/ 17 декабря 2010

Я думаю, что понял вашу проблему. Я проверил изображение, которое вы связали (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 (проверьте комментарий в конце).

Согласно spec , как 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();

надеюсь, это поможет.

4 голосов
/ 10 октября 2013

Кстати, эта проблема исправлена ​​в JDK8 (обратите внимание на фиксацию внизу http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7064516). Я подтвердил, что предварительная сборка JDK8 правильно загружает образы, на которых JDK7 завершается неудачно как описано выше.

2 голосов
/ 22 апреля 2013

Старый пост, но для дальнейшего использования:

Вдохновленный этим вопросом и ссылками, найденными здесь, я написал плагин JPEGImageReader для ImageIO, который поддерживает изображения JPEG с такими "плохими" цветовыми профилями ICC (проблема заключается в том, что цель рендеринга в профиле ICC несовместима с Java ColorConvertOp). Это простая Java и не требует JAI. Исходный код свободно доступен по адресу:

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

...