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
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.
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
OpenJDK 没有本机 JPEG 编码器。尝试使用 Sun 的 JDK,或使用库(例如 JAI)。
AFAIK,关于“粉红色调”,Java 将 JPEG 保存为 ARGB(仍然带有透明度信息)。大多数观众在打开时会假设四个通道必须对应于 CMYK(而不是 ARGB),从而对应于红色色调。
但如果将图像导入回 Java,透明度仍然存在。
OpenJDK does not have a native JPEG encoder. Try using Sun's JDK, or using a library (such as 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.
If you import the image back to Java, the transparency is still there, though.
我在 OpenJDK 7 中遇到了同样的问题,我设法通过使用
TYPE_3BYTE_BGR
的imageType
(而不是使用相同 OpenJDK 的TYPE_4BYTE_ABGR
)来解决此异常。I had the same issue in OpenJDK 7 and I managed to get around this exception by using an
imageType
ofTYPE_3BYTE_BGR
instead ofTYPE_4BYTE_ABGR
using the same OpenJDK.2019 年答案:确保您的 BufferedImage 没有 alpha 透明度。 JPEG 不支持 Alpha,因此如果您的图像有 Alpha,则 ImageIO 无法将其写入 JPEG。
使用以下代码确保您的图像没有 Alpha 透明度:
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.
Use the following code to ensure your image does not have alpha transparancy:
这是一些代码来说明@Thunder将图像类型更改为TYPE_3BYTE_BGR的想法
Here is some code to illustrate @Thunder idea to change the image type to TYPE_3BYTE_BGR
您会收到相同的错误
如果您使用不受支持的色彩空间(在我的例子中为 CYMK), 。请参阅如何在Java中正确从CMYK转换为RGB?如何解决这个问题。
You get the same error
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.
当我获得的图像是 RenderedImage 时,我有一个变化,我使用的是矩形图像表示形式的 Raster,而不是复制字节数组。
根据您的需要,从
ColorModel
获取栅格可能会很有趣。I had a variation when the image I got was a
RenderedImage
, and instead of copying the byte array, I'm using theRaster
which is a rectangular image representation.Depending on your needs it might be interesting to get the raster from the
ColorModel
.