如何在Java中加载大图像 [英] How to load big images in Java

查看:137
本文介绍了如何在Java中加载大图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Java中加载大图像文件,如果文件太大(我已经尝试通过命令行标志增加堆大小),我会收到内存错误消息。

I am trying to load big image files in Java and i am getting a memory error message if the file is too big ( i have already tried increasing the heap size by the command line flag).

我使用以下方式加载图像:

I am loading images with the following way :

如果图像不是tiff图像我正在使用此代码:

If the image is not a tiff image i am using this code:

BufferedImage img = ImageIO.read(fileToOpen);

如果文件是tiff我正在使用此代码:

And if the file is a tiff i am using this code :

BufferedImage img = JAI.create("fileload", 
    fileToOpen.getAbsolutePath()).getAsBufferedImage();

我的问题实际归结为:图像处理程序(例如Photoshop)如何加载文件没有内存错误的数百兆?

My question actually boils down to this: How do image manipulation programs (like Photoshop for instance) load files of hundreds of megabytes without getting memory errors?

我的理解是20MB jpeg难以加载到内存中的原因是因为当加载到BufferedImage中时例如你正在以未压缩的方式保存图像。因此,一种可能的解决方案是拥有一个Java类,该类是Image抽象类的子类,但以压缩形式存储数据。但这可能会有速度问题,因为运行时机器必须在绘制时解压缩数据。另一个选择是将原始未压缩数据缓存到磁盘并从那里无缝读取,但速度问题仍然存在。

It is my understanding that the reason a 20MB jpeg is hard to load into memory is because when loading into a BufferedImage for example you are saving the image in an uncompressed fashion. So one possible solution would be to have a Java class that subclasses the Image abstract class but stores the data in a compressed form. But that would possibly have speed issues as the runtime machine would have to uncompress the data while drawing. Another option would be to cache the raw uncompressed data to disk and seamlessly read from there but the speed problem would still persist.

那么大男孩们如何做呢? Photoshop如何在内存中加载200MB jpeg并绘制所有分辨率而没有任何明显的问题?

So how do the big boys do it? How can Photoshop load a 200MB jpeg in memory and draw all resolutions of it without any apparent issues?

(最后注意事项:在我的应用程序中因为速度问题我得到了BufferedImage我将其内容绘制到具有相同尺寸的VolatileImage上。这大大提高了绘制速度。

(final note: in my application because of speed issues after i get my BufferedImage i draw its contents onto a VolatileImage with the same dimensions. This increases the drawing speed greatly)

推荐答案

未压缩所需的内存RGBA图像宽*高* 4字节。尝试根据此设置你的记忆。底层JDK / DirectX /等可能存在大小上限限制。系统虽然。

The required memory for uncompressed RGBA image is width * height * 4 bytes. Try setting your memory according to this. There might be size cap limitations of the underlying JDK/DirectX/etc. system though.

大男孩利用JPG图像的结构,他们不需要将其加载到内存中。也许他们每次都直接从文件中提取它。

The big boys exploit the structure of the JPG image and they don't need to load it into memory. Perhaps they draw it from file directly, every time.

BufferedImage具有类似于易失性图像的自动加速功能。将加速度优先级设置为1,第一个绘制将在最新的JDK上将其移动到VRAM。

BufferedImage has automatic acceleration capabilities similar to volatile image. Set the acceleration priority to 1 and the first paint will move it to VRAM on latest JDKs.

编辑我认为您运行的是32位系统。如果您的未压缩图像非常大,超过1.4GB,则由于JVM限制,您将无法在内存中处理它。如果图像不是一次性图像,那么您可以找到将其解压缩为临时原始图像的工具,并使用随机文件访问来获取部分图像。

Edit I presume you are running a 32bit system. If your uncompressed image is quite large, more than 1.4GB, you won't be able to handle it in memory due JVM restrictions. If the image is not a one-time image, then you could find tools to stream-uncompress it into a temp-raw image and use random file access to grab parts of it.

这篇关于如何在Java中加载大图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆