用Java创建一个巨大的BufferedImage



伙计们,我想用Java创建一个尺寸为20000 x 20000或更大的巨大BufferedImage,但Java抛出了以下异常:

java.lang.OutOfMemoryError:java堆空间

如何避免此异常?Java有可能创建如此大的图像吗?

虽然增加堆大小当然更容易,但我创建了一个特殊的DataBuffer实现,它允许您将BufferedImage的内存保留在堆外。它使用NIO内存映射文件缓冲区,工作方式类似于虚拟内存。它比使用普通的BufferedImage慢得多,但可能有助于加载和处理过大的图像。

请参阅MappedImageFactory.java和MappedFileBuffer.java了解实现(BSD许可)。

用法简单如下:

int w = 20000;
int h = 20000;
BufferedImage image = MappedImageFactory
.createCompatibleMappedImage(w, h, BufferedImage.TYPE_INT_ARGB);

我已经成功地使用它来加载和显示一个只有32MB堆的2GB图像。

请确保,要使用64位java和64位系统:

在大多数现代32位Windows系统上,最大堆大小将在1.4G到1.6G之间。在32位Solaris内核上,地址空间限制为2G。在运行32位虚拟机的64位操作系统上,最大堆大小可能更高,在许多Solaris系统上接近4G

然后添加一些堆:

尝试-Xmx2048m或-Xmx2g

到您的"java"调用(JVM参数)

因为如果你使用RGB或ARGB类型的图像,那么每个像素都是int类型

20 000 x 20 000=40 000 000*4(int有4个字节)=约400 MB*4=约1600 MB

假设您希望拥有更大的映像,并且您的应用程序需要一些空间,以及JVM,您可能希望拥有更多或更少的堆,那么您需要做出决定。

如果你有4GB的RAM,正如你在问题下面的一些评论中所说,这会限制你可以创建的图像的大小,你需要从4GB中减去系统、其他应用程序和JVM的RAM数量,那么你就不能创建比你剩下的内存更大的图像。

您可以创建一个black&白色图像(1位/像素)如下:

IndexColorModel colorModel = new IndexColorModel(
1,                           // bits per pixel
2,                           // number of colors
new byte[]{0, (byte) 0xff},  // red values
new byte[]{0, (byte) 0xff},  // green values
new byte[]{0, (byte) 0xff}); // blue values
BufferedImage image = new BufferedImage(20000, 20000,
BufferedImage.TYPE_BYTE_BINARY, colorModel);

需要20000*20000位=50 MB。

相关内容

最新更新