内存不足问题,保存大型BufferedImage

时间:2011-07-14 10:40:42

标签: java image save bufferedimage

我在保存大型(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) {
    }


}

提前谢谢!

2 个答案:

答案 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这样的原生图像缩放器。