保存大型 BufferedImage 时出现内存不足问题
我在保存大(fe 12 000 x 9 000)图像时遇到问题。
我正在开发一个图形编辑软件(类似于简单的 Photoshop)并且 用户显然必须具备保存图像的能力。
假设我想将图像保存为 .png。 JAVA总是需要使用BufferedImage来保存绘制的东西吗?
我知道图像大小的方程式是: X尺寸 * Y尺寸 * 4(红、绿、蓝、alpha) 因此,在本例中我们获得了超过 400 MB 的空间。
我知道我可以将图像保存为多个部分(图块),但用户无论如何都必须以某种方式合并它们。
有没有其他方法可以在不使用 BufferedImage 的情况下保存这么大的图像?
保存图像的代码:
public static void SavePanel() {
BufferedImage image = null;
image = new BufferedImage(
(int) (Main.scale * sizeX ),
(int) (Main.scale * sizeY ),
BufferedImage.TYPE_INT_RGB);
g2 = image.createGraphics();
panel.paint(g2);
try {
ImageIO.write(image, "png", new File(FactoryDialog.ProjectNameTxt.getText() + ".png"));
} catch (IOException e) {
}
}
先谢谢您!
I have a problem saving large (f.e. 12 000 x 9 000 ) images.
I'm developing a graphical editing software ( something like simple Photoshop ) and
The user obviously has to have to ability to save the image.
Lets say I would like to save the image as .png.
Does JAVA always need to use the BufferedImage for saving drawn stuff ?
I know the equation for size of the image is:
Xsize * Ysize * 4 ( red, green, blue, alpha )
So in this case we get over 400 MB.
I know I could save the image in parts ( tiles ) but the user would have to merge them somehow anyway.
Is there any other way to save such a large image without using the BufferedImage ?
Code for saving the image:
public static void SavePanel() {
BufferedImage image = null;
image = new BufferedImage(
(int) (Main.scale * sizeX ),
(int) (Main.scale * sizeY ),
BufferedImage.TYPE_INT_RGB);
g2 = image.createGraphics();
panel.paint(g2);
try {
ImageIO.write(image, "png", new File(FactoryDialog.ProjectNameTxt.getText() + ".png"));
} catch (IOException e) {
}
}
Thank you in advance !
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(2)
ImageIO.write(..)
方法接受 RenderedImage
,而不仅仅是 BufferedImage
。不久前我成功地利用了这个事实来写出非常大的图像。通常,编写器实现会按顺序写出图像,并仅向 RenderedImage 询问它们当前需要的片段。
通过查看您的代码,我认为应该可以破解一个 RenderedImage
实现,该实现将您的 panel
放入其构造函数中,并可以传递给 ImageIO
> 用于写作。在此过程中,ImageIO
将从您的图像请求数据。然后,您可以使用该面板动态创建请求的片段(Raster
内容)。这样,整个图像在任何时候都不必存储在内存中。这种方法的出发点是
public class PanelImage implements RenderedImage {
private final Panel panel;
public PanelImage(Panel panel) {
this.panel = panel;
}
/* implement all the missing methods, don't be afraid, most are trivial */
}
显然,您还应该检查您的面板是否没有遇到与 BufferedImage 相同的问题。根据应用程序的性质,无论如何,您都必须在内存中至少保存一次图像(使用图块取模)。但这样至少可以避免重复。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
使用像 image magick 这样的原生图像缩放器。
Using native image resizer like image magick instead.