![](/img/trans.png)
[英]Using ImageIO.write() to create a JPEG creates a 0 byte file
[英]ImageIO not able to write a JPEG file
我有一个 BufferedImage 我正在尝试写入一个 jpeg 文件,但我的 Java 程序抛出异常。 我能够成功地将相同的缓冲区保存为 gif 和 png。 我试过在谷歌上四处寻找解决方案,但无济于事。
代码:
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
OpenJDK没有原生JPEG编码器,尝试使用Sun的JDK,或使用库(如JAI)
AFAIK,关于“粉红色调”,Java将JPEG保存为ARGB(仍然具有透明度信息)。 大多数观众在打开时假设四个频道必须对应于CMYK(不是ARGB),因此必须是红色。
如果将图像导回到Java,透明度仍然存在。
我有同样的问题在OpenJDK 7的,我设法通过使用得到这个例外各地imageType
的TYPE_3BYTE_BGR
代替TYPE_4BYTE_ABGR
使用相同的OpenJDK。
这是一些代码来说明@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();
}
你得到同样的错误
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)。 请参阅如何正确地在Java中将CMYK转换为RGB? 怎么解决这个问题。
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;
}
当我得到的图像是RenderedImage
时,我有一个变化,而不是复制字节数组,我使用的是Raster
,它是一个矩形图像表示。
var newBufferedImage = new BufferedImage(
renderImg.getWidth(),
renderImg.getHeight(),
BufferedImage.TYPE_INT_RGB
);
renderImg.copyData(newBufferedImage.getRaster());
根据您的需要,从ColorModel
获取栅格可能会很有趣。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.