将 PNG 转换为 JPEG
我在将简单的 PNG 转换为 JPEG 格式时遇到问题。 我正在使用以下代码:
...
File png = new File(filePath);
try {
SeekableStream s = new FileSeekableStream(png);
PNGDecodeParam pngParams = new PNGDecodeParam();
ImageDecoder dec = ImageCodec.createImageDecoder("png", s, pngParams);
RenderedImage pngImage = dec.decodeAsRenderedImage();
JPEGEncodeParam jparam = new JPEGEncodeParam();
jparam.setQuality(0.50f); // e.g. 0.25f
File jpeg = new File("jpeg.jpeg");
FileOutputStream out = new FileOutputStream(jpeg);
ImageEncoder encoder = ImageCodec.createImageEncoder("JPEG", out, jparam);
encoder.encode(pngImage);
s.close();
} catch (IOException e) {
ok = false;
e.printStackTrace();
}
return ok;
}
...
我最终遇到了 JAI 异常 -> java.lang.RuntimeException:只能写入 1 或 3 段字节数据。 在 com.sun.media.jai.codecimpl.JPEGImageEncoder.encode(JPEGImageEncoder.java:148) ...
没有选项。有什么建议吗?
I'm having problems converting a simple PNG into a JPEG format.
I'm using the following code:
...
File png = new File(filePath);
try {
SeekableStream s = new FileSeekableStream(png);
PNGDecodeParam pngParams = new PNGDecodeParam();
ImageDecoder dec = ImageCodec.createImageDecoder("png", s, pngParams);
RenderedImage pngImage = dec.decodeAsRenderedImage();
JPEGEncodeParam jparam = new JPEGEncodeParam();
jparam.setQuality(0.50f); // e.g. 0.25f
File jpeg = new File("jpeg.jpeg");
FileOutputStream out = new FileOutputStream(jpeg);
ImageEncoder encoder = ImageCodec.createImageEncoder("JPEG", out, jparam);
encoder.encode(pngImage);
s.close();
} catch (IOException e) {
ok = false;
e.printStackTrace();
}
return ok;
}
...
I end up with an JAI exception ->
java.lang.RuntimeException: Only 1, or 3-band byte data may be written.
at com.sun.media.jai.codecimpl.JPEGImageEncoder.encode(JPEGImageEncoder.java:148) ...
Ran out of options. Any suggestion?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
使用
ImageIO
将 PNG 读入BufferedImage
并以 JPEG 格式写出图像。附录:在这种方法中,转换由作者的
ImageTranscoder
。It might be easier to use
ImageIO
to read the PNG into aBufferedImage
and write the image out in JPEG format.Addendum: In this approach, the conversion is handled transparently by the writer's
ImageTranscoder
.在尝试写入 jpg 之前,您可能需要在 png 中删除 alpha 通道。
创建类型为 TYPE_INT_RGB(不是 TYPE_INT_ARGB)的新 BufferedImage,然后将源图像 (pngImage) 写入新的空白图像。
像这样的东西(警告,未经测试的代码):
you probably have alpha channel in the png that you need to get rid of before trying to write the jpg.
Create a new BufferedImage with type TYPE_INT_RGB (not TYPE_INT_ARGB), and then write your source image (pngImage) onto the new blank image.
Something like this (warning, not tested code):
我还发现使用 ImageIO (Java 6) 将 PNG 图像读入 BufferedImage 并将其写入 JPG“格式名称”会损坏图像。图像就在那里,但颜色看起来“日晒”并且几乎颠倒了。 JPG 文件肯定比 PNG 文件小得多,因此进行了大量压缩。我不知道你如何控制压缩或颜色深度。
I also found that reading a PNG image into a BufferedImage with ImageIO (Java 6) and writing it out to a JPG "format name" corrupted the image. The image was there, but the colors looked "solarized" and almost inverted. The JPG file was much smaller than the PNG file for sure, so a lot of compression was done. I don't see how you might control the compression or color depth.
使用其他解决方案转换后,我的文件已损坏,但此方法对我有用:
I had corrupted file after conversion with other solutions but this method worked for me:
我假设 JAI 使用索引颜色模型读取 PNG 图像,并且只能将 8 位灰度或 24 位彩色图像写入为 JPEG 文件。
如果您不需要使用 JAI 来完成此任务,您应该可以使用 ImageIO 来代替:
I suppse that JAI reads the PNG image with an indexed colour model and is only able to write 8-bit grayscale or 24-bit colour images as JPEG files.
If you are not required to use JAI for this task, you should be able to use ImageIO instead:
我在稍微不同的上下文中收到以下消息。摆脱 Alpha 通道解决了问题
I was getting the following message in a slightly different context. Getting rid of the alpha channel solved the problem
参阅使用java将透明gif / png转换为jpeg
请 查看harmanjd发布的使用图形环境重绘的解决方案。使用 DirectColorModel 的解决方案无法编译,应将其清除。我没有足够的代表点来直接发表评论。
see Converting transparent gif / png to jpeg using java
Have a look at the solution that redraws with the graphics environment posted by harmanjd. The solution with the DirectColorModel doesn't compile and should be wiped away. I don't have enough rep points to comment directly there.