【问题标题】:Out of memory problem saving large BufferedImage保存大 BufferedImage 的内存不足问题
【发布时间】:2011-10-05 05:39:34
【问题描述】:

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


}

提前谢谢你!

【问题讨论】:

    标签: java image save bufferedimage


    【解决方案1】:

    改用像 image magick 这样的原生图像调整器。

    【讨论】:

      【解决方案2】:

      ImageIO.write(..) 方法接受 RenderedImage,而不仅仅是 BufferedImage。我前段时间成功地利用了这个事实来写出非常大的图像。通常,writer 实现顺序写出图像,并仅向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 相同的问题。根据您的应用程序的性质,您必须至少将图像保存在内存中一次(使用图块进行模运算)。但是这样至少可以避免重复。

      【讨论】:

      • 听起来不错,但我在实现 getSampleModel 和 getData(rect) 方法时遇到了一些麻烦(对这些方法不太熟悉)
      • 您可以在这些方法中创建BufferedImage,将感兴趣的区域绘制到其中,然后返回RasterSampleModel。如果这本身就是一个问题,那么就这些问题发布一个单独的问题可能是个好主意,这样我们就不必在 cmets 中讨论它了。
      • 好的,谢谢你的帮助,我的光栅有点问题,但我想我会在另一个问题中解决
      • 如果你可以看看这里 - stackoverflow.com/questions/6705352/… 我在那里指定了我的问题
      猜你喜欢
      • 1970-01-01
      • 2019-03-18
      • 2013-08-07
      • 2015-04-15
      • 2019-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-06
      相关资源
      最近更新 更多