在Java中创建稀疏的BufferedImage

3

我需要创建一个非常高分辨率的图像,但是图像相对“稀疏”,只有图像中的某些区域需要绘制。

例如以下代码:

/* this take 5GB memory */

    final BufferedImage img = new BufferedImage( 36000, 36000, BufferedImage.TYPE_INT_ARGB);

/* draw something */

    Graphics g = img.getGraphics();
    g.drawImage(....);

/* output as PNG */

    final File out = new File("out.png"); 
    ImageIO.write(img, "png", out); 

我创建的最终PNG图像仅约为200~300MB。

问题是,我如何避免在开始时创建一个5GB的BufferedImage?我确实需要具有大尺寸但只包含非常稀疏颜色信息的图像。

是否有BufferedImage的流,以便它不会占用太多内存?


PNG在创建时使用DEFLATE算法进行压缩,因此它比“BufferedImage”要小得多,这并不奇怪。 - Powerlord
2个回答

1

不使用延迟初始化的Map或类似的结构,其中包含许多较小的BufferedImage,是否有原因?

编辑:那是一个非常专业的数据结构。如果您想在图像上绘制,请以某种合理的方式平铺它们,并对每个图像应用相应的AffineTransform。然后,您可以遍历集合并绘制到每个图像上,如果它是空白的,则将其置为空或Flyweight。但我不知道如何在Java中无痛地将它们全部组合成一个PNG。


0

你的示例使用了TYPE_INT_ARGB作为图像类型,每个像素占用4个字节。如果图像颜色数量有限,你可以尝试使用其他像素占用更少字节数的图像类型。

这样可以减少每个像素的字节数,但最好的情况是每个像素只占用1个字节,即使这样仍然会使用超过1 GB 的内存。

否则,你可以尝试将渲染分成多个图像,并将它们分别合并在一起。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接