Java ImageIO 无法写入 JPEG 文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3432388/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 00:44:39  来源:igfitidea点击:

ImageIO not able to write a JPEG file

javaimagejpegjavax.imageio

提问by Karan

I have a BufferedImage I'm trying to write to a jpeg file, but my Java program throws an exception. I'm able to successfully save the same buffer to a gif and png. I've tried looking around on Google for solutions, but to no avail.

我有一个 BufferedImage 我正在尝试写入 jpeg 文件,但我的 Java 程序抛出异常。我能够成功地将相同的缓冲区保存为 gif 和 png。我试过在谷歌上四处寻找解决方案,但无济于事。

Code:

代码:

   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:

例外:

 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

采纳答案by Rui Vieira

OpenJDK does not have a native JPEG encoder, try using Sun's JDK, or using a library (such as JAI

OpenJDK 没有原生的 JPEG 编码器,尝试使用 Sun 的 JDK,或者使用一个库(例如JAI

AFAIK, regarding the "pinkish tint", Java saves the JPEG as ARGB (still with transparency information). Most viewers, when opening, assume the four channels must correspond to a CMYK (not ARGB) and thus the red tint.

AFAIK,关于“粉红色调”,Java 将 JPEG 保存为 ARGB(仍然带有透明度信息)。大多数观众在打开时假设四个通道必须对应于 CMYK(而非 ARGB),因此是红色。

If you import the image back to Java, the transparency is still there, though.

但是,如果将图像导入回 Java,透明度仍然存在。

回答by Thunder

I had the same issue in OpenJDK 7 and I managed to get around this exception by using an imageTypeof TYPE_3BYTE_BGRinstead of TYPE_4BYTE_ABGRusing the same OpenJDK.

我在 OpenJDK 7 中遇到了同样的问题,我设法通过使用imageTypeofTYPE_3BYTE_BGR而不是TYPE_4BYTE_ABGR使用相同的 OpenJDK来解决这个异常。

回答by rmuller

You get the same error

你得到同样的错误

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)

if you are using a not supported Color Space (in my case CYMK). See How to convert from CMYK to RGB in Java correctly?how to solve this.

如果您使用的是不受支持的色彩空间(在我的情况下是 CYMK)。请参阅如何在 Java 中正确地从 CMYK 转换为 RGB?如何解决这个问题。

回答by Adam Gawne-Cain

2019 answer: Make sure your BufferedImage does not have alpha transparency. JPEG does not support alpha, so if your image has alpha then ImageIO cannot write it to JPEG.

2019 答案:确保您的 BufferedImage 没有 alpha 透明度。JPEG 不支持 alpha,因此如果您的图像具有 alpha,则 ImageIO 无法将其写入 JPEG。

Use the following code to ensure your image does not have alpha transparancy:

使用以下代码确保您的图像没有 alpha 透明度:

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;
}

回答by Peter Quiring

Here is some code to illustrate @Thunder idea to change the image type to TYPE_3BYTE_BGR

这是一些代码来说明@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();
}