ImageIO无法写入JPEG文件

Kar*_*ran 48 java jpeg image javax.imageio

我有一个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);
   }
Run Code Online (Sandbox Code Playgroud)

例外:

 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
Run Code Online (Sandbox Code Playgroud)

Rui*_*ira 39

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

AFAIK,关于"粉红色调",Java将JPEG保存为ARGB(仍然具有透明度信息).大多数观众在打开时假设四个频道必须对应于CMYK(不是ARGB),因此必须是红色.

如果将图像导回到Java,透明度仍然存在.

  • 顺便说一句,OpenJDK确实有一个原生的JPEG编码器.如果您尝试保存32位颜色文件 - 它会失败.并且Sun JDK不会失败,而是形成有色文件.不确定什么是更好的. (8认同)

Thu*_*der 34

我有同样的问题在OpenJDK 7的,我设法通过使用得到这个例外左右imageTypeTYPE_3BYTE_BGR,而不是TYPE_4BYTE_ABGR使用相同的OpenJDK.

  • 你是对的!!!我创建了一个新的TYPE_3BYTE_BGR的BufferedImage,并使用了来自TYPE_INT_ARGB的BufferedImage的getRGB()和新的BufferedImage的setRGB(),然后调用了ImageIO.write(),它在Linux上运行. (3认同)

Ada*_*ain 20

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

使用以下代码确保您的图像没有 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;
}
Run Code Online (Sandbox Code Playgroud)


Pet*_*ing 8

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