Java ImageIO IIOException: неподдерживаемый тип изображения?
Работа с изображениями в Java в первый раз, и я получаю некоторые необычные исключения, которые не документированы очень хорошо. Здесь строка кода, которая терпит неудачу:
BufferedImage imgSelected = ImageIO.read(new File("/abs/url/to/file/image.jpg"));
Эта строка генерирует исключение IIOException с неподдерживаемым типом изображения в качестве сообщения об исключении. Я проверил и повторно проверил, что на самом деле эта строка бросает исключение, что объект File действителен, что URL-адрес действителен и что image.jpg
на самом деле является допустимым JPG, который загружается отлично в другом изображении зрители.
Что я могу сделать, чтобы получить дополнительную информацию о характере этого исключения? Является ли это традиционным способом загрузки изображений в Java 7 или это старый/устаревший метод? Там не так много информации об этих исключениях "Неподдерживаемый тип изображения", и, безусловно, JPG с поддержкой ImageIO!
Спасибо за любую помощь!
Ответы
Ответ 1
Попробуйте проверить кодировку JPEG. ImageIO
не может читать изображения JPEG в кодировке CMYK. AFAIK, ImageIO не обновлялась годами, поэтому вы хотели бы попробовать и использовать официальную альтернативу/расширение: JAI ImageIO.
К сожалению, JAI ImageIO нуждается в некоторых собственных библиотеках, установленных в JRE, что может быть нежелательным. Мы делаем следующее:
- используйте Apache Sanselan, чтобы определить, является ли он JPEG
- поскольку Sanselan не может читать и записывать JPEG, используйте обычный старый AWT
JPEGCodec
: JPEGCodec.createJPEGDecoder(...)
- чтобы преобразовать CMYK в RGB, мы получаем растр прочитанного
BufferedImage
и вручную конвертируем его (вы можете использовать профили ICC, но ручное преобразование соответствует нашим потребностям)
Вот мой вопрос, который возник из-за того, что ImageIO
не поддерживает все типы изображений JPEG, и я изложил здесь немного больше своих выводов о том, почему вы получаете это сообщение: Чистая Java-альтернатива JAI ImageIO для обнаружения изображений CMYK.
Ответ 2
Я, к сожалению, сталкивался со многими стандартными нарушениями файлов JPEG. ImageIO особенно придирчив и часто отказывается загружать изображения, которые часто загружаются и, по-видимому, отображаются корректно другим программным обеспечением с менее строгими проверками формата файла.
Это не очень красиво, но одним обходным путем является использование внутреннего декодера JPEG для виртуальных машин Oracle (com.sun.image.codec.jpeg.JPEGCodec), поскольку он, по-видимому, допускает больше отклонения спецификации в качестве обертки ImageIO:
BufferedImage img =
JPEGCodec.createJPEGDecoder(inputStream).decodeAsBufferedImage();
Это, конечно, не идеальное решение, так как использование конкретных классов реализации блокирует вас к конкретному поставщику VM и может ломаться с более новыми версиями VM, но если вы будете использовать программное обеспечение только в контролируемой среде, это может быть лучше, чем никакого решения.
Ответ 3
Другой вариант - использовать .jar, подготовленный Вернером Рандельсхофером:
http://www.randelshofer.ch/blog/2011/08/reading-cmyk-jpeg-images-with-java-imageio/ или библиотека Монте-медиа: http://www.randelshofer.ch/monte/
Это выглядит довольно легко и похоже на использование ImageIO и доступно под лицензией CC.