Невозможно прочитать изображение в формате JPEG с помощью ImageIO.read (Файл)

У меня возникают проблемы с чтением этого одного файла JPEG с помощью ImageIO.read (Файл файла) – он выдает исключение с сообщением «Неподдерживаемый тип изображения».

Я пробовал другие изображения JPEG, и они, похоже, работают нормально.

Единственное различие, которое я смог обнаружить, состоит в том, что этот файл содержит миниатюру – известно, что это вызывает проблемы с ImageIO.read ()?

Недостаточное изображение

РЕДАКТИРОВАТЬ:

Добавлено результирующее изображение:

Странные цвета

Ваше изображение «Цветная модель» – это CMYK, JPEGImageReader (внутренний class, который читает ваш файл) читает только цветную модель RGB.

Если вы настаиваете на чтении изображений CMYK, вам нужно будет их преобразовать, попробуйте этот код.

ОБНОВИТЬ

Прочтите изображение CMYK в RGB BufferedImage.

  File f = new File("/path/imagefile.jpg"); //Find a suitable ImageReader Iterator readers = ImageIO.getImageReadersByFormatName("JPEG"); ImageReader reader = null; while(readers.hasNext()) { reader = (ImageReader)readers.next(); if(reader.canReadRaster()) { break; } } //Stream the image file (the original CMYK image) ImageInputStream input = ImageIO.createImageInputStream(f); reader.setInput(input); //Read the image raster Raster raster = reader.readRaster(0, null); //Create a new RGB image BufferedImage bi = new BufferedImage(raster.getWidth(), raster.getHeight(), BufferedImage.TYPE_4BYTE_ABGR); //Fill the new image with the old raster bi.getRaster().setRect(raster); 

UPDATE – март 2015 г. – добавление имитационных изображений

Исходные изображения были удалены из Dropbox. Поэтому я добавляю новые изображения (а не оригиналы), которые имитируют проблему, которая с ними происходит.

Первое изображение – как выглядит обычное изображение RGB.

Изображение RGB

Второе изображение – это то, как будет выглядеть одно и то же изображение в цветовой модели CMYK.

Вы не можете увидеть, как он выглядит в Интернете, потому что он будет преобразован в RGB хостом. Чтобы узнать, как это выглядит, возьмите изображение RGB и запустите его через конвертер RGB в CMYK.

Третье изображение – это то, как будет выглядеть изображение CMYK при чтении, затем написании с использованием Java ImageIO.

Изображение CMYK читается через Java RGB

Проблема, которая происходила с OP, – это что-то вроде изображения 2, которое выдает исключение, когда вы пытаетесь его прочитать.

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

Вдохновленный этим вопросом и ссылками, найденными здесь, я написал плагин JPEGImageReader для ImageIO, который поддерживает цветные модели CMYK (как с оригинальной цветовой моделью, так и с неявным преобразованием в RGB при чтении). Читатель также выполняет правильное преобразование цветов, используя профиль ICC, встроенный в stream JPEG, в отличие от других решений, упомянутых здесь.

Это простая Java и не требует JAI. Исходный код и бинарные дистрибутивы свободно доступны в github.com/haraldk/TwelveMonkeys и покрываются лицензией типа BSD.

После того, как вы его установили, вы можете читать CMYK JPEG с помощью ImageIO.read(...) следующим образом:

 File cmykJPEGFile = new File(/*path*/); BufferedImage image = ImageIO.read(cmykJPEGFile); 

Т.е.: В большинстве случаев нет необходимости изменять код.

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

Для решения требуется Sanselan (или Apache Commons Imaging, как его сейчас называют), и для этого требуется разумный цветовой профиль CMYK (файл .icc). Вы можете получить более позднюю версию от Adobe или от eci.org.

Основная проблема заключается в том, что Java – из коробки – может читать только файлы JPEG в RGB. Если у вас есть файл CMYK, вам нужно различать обычный CMYK, Adobe CMYK (с инвертированными значениями, то есть 255 без чернил и 0 для максимальных чернил) и Adobe CYYK (в некотором варианте с инвертированными цветами).

 public class JpegReader { public static final int COLOR_TYPE_RGB = 1; public static final int COLOR_TYPE_CMYK = 2; public static final int COLOR_TYPE_YCCK = 3; private int colorType = COLOR_TYPE_RGB; private boolean hasAdobeMarker = false; public BufferedImage readImage(File file) throws IOException, ImageReadException { colorType = COLOR_TYPE_RGB; hasAdobeMarker = false; ImageInputStream stream = ImageIO.createImageInputStream(file); Iterator iter = ImageIO.getImageReaders(stream); while (iter.hasNext()) { ImageReader reader = iter.next(); reader.setInput(stream); BufferedImage image; ICC_Profile profile = null; try { image = reader.read(0); } catch (IIOException e) { colorType = COLOR_TYPE_CMYK; checkAdobeMarker(file); profile = Sanselan.getICCProfile(file); WritableRaster raster = (WritableRaster) reader.readRaster(0, null); if (colorType == COLOR_TYPE_YCCK) convertYcckToCmyk(raster); if (hasAdobeMarker) convertInvertedColors(raster); image = convertCmykToRgb(raster, profile); } return image; } return null; } public void checkAdobeMarker(File file) throws IOException, ImageReadException { JpegImageParser parser = new JpegImageParser(); ByteSource byteSource = new ByteSourceFile(file); @SuppressWarnings("rawtypes") ArrayList segments = parser.readSegments(byteSource, new int[] { 0xffee }, true); if (segments != null && segments.size() >= 1) { UnknownSegment app14Segment = (UnknownSegment) segments.get(0); byte[] data = app14Segment.bytes; if (data.length >= 12 && data[0] == 'A' && data[1] == 'd' && data[2] == 'o' && data[3] == 'b' && data[4] == 'e') { hasAdobeMarker = true; int transform = app14Segment.bytes[11] & 0xff; if (transform == 2) colorType = COLOR_TYPE_YCCK; } } } public static void convertYcckToCmyk(WritableRaster raster) { int height = raster.getHeight(); int width = raster.getWidth(); int stride = width * 4; int[] pixelRow = new int[stride]; for (int h = 0; h < height; h++) { raster.getPixels(0, h, width, 1, pixelRow); for (int x = 0; x < stride; x += 4) { int y = pixelRow[x]; int cb = pixelRow[x + 1]; int cr = pixelRow[x + 2]; int c = (int) (y + 1.402 * cr - 178.956); int m = (int) (y - 0.34414 * cb - 0.71414 * cr + 135.95984); y = (int) (y + 1.772 * cb - 226.316); if (c < 0) c = 0; else if (c > 255) c = 255; if (m < 0) m = 0; else if (m > 255) m = 255; if (y < 0) y = 0; else if (y > 255) y = 255; pixelRow[x] = 255 - c; pixelRow[x + 1] = 255 - m; pixelRow[x + 2] = 255 - y; } raster.setPixels(0, h, width, 1, pixelRow); } } public static void convertInvertedColors(WritableRaster raster) { int height = raster.getHeight(); int width = raster.getWidth(); int stride = width * 4; int[] pixelRow = new int[stride]; for (int h = 0; h < height; h++) { raster.getPixels(0, h, width, 1, pixelRow); for (int x = 0; x < stride; x++) pixelRow[x] = 255 - pixelRow[x]; raster.setPixels(0, h, width, 1, pixelRow); } } public static BufferedImage convertCmykToRgb(Raster cmykRaster, ICC_Profile cmykProfile) throws IOException { if (cmykProfile == null) cmykProfile = ICC_Profile.getInstance(JpegReader.class.getResourceAsStream("/ISOcoated_v2_300_eci.icc")); ICC_ColorSpace cmykCS = new ICC_ColorSpace(cmykProfile); BufferedImage rgbImage = new BufferedImage(cmykRaster.getWidth(), cmykRaster.getHeight(), BufferedImage.TYPE_INT_RGB); WritableRaster rgbRaster = rgbImage.getRaster(); ColorSpace rgbCS = rgbImage.getColorModel().getColorSpace(); ColorConvertOp cmykToRgb = new ColorConvertOp(cmykCS, rgbCS, null); cmykToRgb.filter(cmykRaster, rgbRaster); return rgbImage; } } 

Код сначала пытается прочитать файл, используя обычный метод, который работает для файлов RGB. Если он терпит неудачу, он считывает детали цветовой модели (профиль, маркер Adobe, вариант Adobe). Затем он считывает необработанные пиксельные данные (растровые) и выполняет все необходимые преобразования (YCCK в CMYK, инвертированные цвета, CMYK в RGB).

Я не очень доволен своим решением. В то время как цвета в основном хороши, темные области немного яркие, в частности черные не полностью черные. Если кто-нибудь знает, что я могу улучшить, я был бы рад услышать это.

ImageIO.read() ->

 File filePath = new File("C:\\Users\\chang\\Desktop\\05036877.jpg"); com.sun.image.codec.jpeg.JPEGImageDecoder jpegDecoder = JPEGCodec.createJPEGDecoder (new FileInputStream(filePath)); BufferedImage image = jpegDecoder.decodeAsBufferedImage(); 

Я нашел https: //stackoverflow.com/questions/22409 … здесь тоже, это делает отличное преобразование цвета

И объединить оба, чтобы получить это:

 private BufferedImage convertCMYK2RGB(BufferedImage image) throws IOException{ log.info("Converting a CYMK image to RGB"); //Create a new RGB image BufferedImage rgbImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_3BYTE_BGR); // then do a funky color convert ColorConvertOp op = new ColorConvertOp(null); op.filter(image, rgbImage); return rgbImage; } 

Я исправлю это. нужно только добавить эту зависимость. Я могу читать изображение CMYK с помощью ImageIO. TwelveMonkeys

 ImageIO.read(new URL("http://img3.tianyancha.com/api/9b80a61183787909e719c77fd0f78103.png")) 
  • Пакетное преобразование PNG в JPG в Linux
  • Как автоматически поворачивать изображения на основе данных EXIF?
  • Можем ли мы изменить размер изображения JPEG без декодирования и перекодировать его?
  • Как вы создаете уменьшенное изображение из JPEG на Java?
  • Значимые миниатюры для видео с использованием FFmpeg
  • Какая метаинформация содержится в файле изображения?
  • Чтение проблем JPEG Метаданные (ориентация)
  • Как найти качество JPG?
  • C # Как проверить файл на jpeg?
  • Стеганография при сжатии с потерей (JAVA)
  • Как я могу сделать Windows Paint сохранить по умолчанию в формате JPEG?
  • Давайте будем гением компьютера.