Подтвердить что ты не робот

ImageIO не удалось записать файл JPEG

У меня есть BufferedImage. Я пытаюсь записать файл jpeg, но моя Java-программа выдает исключение. Я могу успешно сохранить тот же буфер в gif и png. Я пробовал искать в Google решения, но безрезультатно.

код:

   File outputfile = new File("tiles/" + row + ":" + col + ".jpg");
   try {
       ImageIO.write(mapBufferTiles[row][col], "jpg", outputfile);
   } catch (IOException e) {
        outputfile.delete();
        throw new RuntimeException(e);
   }

Исключение:

 Exception in thread "main" java.lang.RuntimeException: javax.imageio.IIOException: Invalid argument to native writeImage
 at MapServer.initMapBuffer(MapServer.java:90)
 at MapServer.<init>(MapServer.java:24)
 at MapServer.main(MapServer.java:118)
 Caused by: javax.imageio.IIOException: Invalid argument to native writeImage
 at com.sun.imageio.plugins.jpeg.JPEGImageWriter.writeImage(Native Method)
 at com.sun.imageio.plugins.jpeg.JPEGImageWriter.writeOnThread(JPEGImageWriter.java:1055)
 at com.sun.imageio.plugins.jpeg.JPEGImageWriter.write(JPEGImageWriter.java:357)
 at javax.imageio.ImageWriter.write(ImageWriter.java:615)
 at javax.imageio.ImageIO.doWrite(ImageIO.java:1602)
 at javax.imageio.ImageIO.write(ImageIO.java:1526)
 at MapServer.initMapBuffer(MapServer.java:87)
 ... 2 more
4b9b3361

Ответ 1

OpenJDK не имеет встроенного кодировщика JPEG, попробуйте использовать Sun JDK или использовать библиотеку (например, JAI

AFAIK, в отношении "розоватого оттенка", Java сохраняет JPEG как ARGB (все еще с информацией о прозрачности). Большинство зрителей при открытии предполагают, что четыре канала должны соответствовать CMYK (а не ARGB) и, следовательно, красному оттенку.

Если вы импортируете изображение обратно в Java, прозрачность все еще существует.

Ответ 2

У меня была такая же проблема в OpenJDK 7, и мне удалось обойти это исключение, используя imageType of TYPE_3BYTE_BGR вместо TYPE_4BYTE_ABGR, используя тот же OpenJDK.

Ответ 3

Вот некоторый код, чтобы проиллюстрировать идею @Thunder, чтобы изменить тип изображения на TYPE_3BYTE_BGR

try {
  BufferedImage input = ImageIO.read(new File("input.png"));
  System.out.println("input image type=" + input.getType());
  int width = input.getWidth();
  int height = input.getHeight();
  BufferedImage output = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
  int px[] = new int[width * height];
  input.getRGB(0, 0, width, height, px, 0, width);
  output.setRGB(0, 0, width, height, px, 0, width);
  ImageIO.write(output, "jpg", new File("output.jpg"));
} catch (Exception e) {
  e.printStackTrace();
}

Ответ 4

Вы получаете ту же ошибку

Caused by: javax.imageio.IIOException: Invalid argument to native writeImage
at com.sun.imageio.plugins.jpeg.JPEGImageWriter.writeImage(Native Method)
at com.sun.imageio.plugins.jpeg.JPEGImageWriter.writeOnThread(JPEGImageWriter.java:1055)

если вы используете не поддерживаемое цветовое пространство (в моем случае CYMK). См. Как правильно преобразовать из CMYK в RGB в Java? Как решить эту проблему.

Ответ 5

Ответ 2019: убедитесь, что ваш BufferedImage не имеет альфа-прозрачности. JPEG не поддерживает альфа, поэтому если у вашего изображения есть альфа, то ImageIO не сможет записать его в JPEG.

Используйте следующий код, чтобы убедиться, что ваше изображение не имеет альфа-прозрачности:

static BufferedImage ensureOpaque(BufferedImage bi) {
    if (bi.getTransparency() == BufferedImage.OPAQUE)
        return bi;
    int w = bi.getWidth();
    int h = bi.getHeight();
    int[] pixels = new int[w * h];
    bi.getRGB(0, 0, w, h, pixels, 0, w);
    BufferedImage bi2 = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    bi2.setRGB(0, 0, w, h, pixels, 0, w);
    return bi2;
}