我在保存大型(f.e. 12 000 x 9 000)图像时遇到问题。
我正在开发一个图形编辑软件(类似于简单的Photoshop)和 用户显然必须能够保存图像。
让我们说我想将图像保存为.png。 JAVA总是需要使用BufferedImage来保存绘制的东西吗?
我知道图像大小的等式是: Xsize * Ysize * 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) {
}
}
提前谢谢!
答案 0 :(得分:6)
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 */
}
显然,您还应该检查panel
是否没有遇到与BufferedImage
相同的问题。根据应用程序的性质,您必须至少在内存中保存一次图像(使用图块模数)。但这样你至少可以避免重复。
答案 1 :(得分:0)
使用像magick这样的原生图像缩放器。