如何在非常大的BMP上进行图像处理?

问题描述:

我正试图在一组非常大(几GB)的BMP图像文件上进行一些操作(具体来说,转换为不同类型的拆分成磁贴)。如何在非常大的BMP上进行图像处理?

我不确定我是否理解BMP文件格式,但需要将整个文件加载到内存中吗?我无法找到任何不需要加载整个文件的API。 ImageMagick也无法做到这一点。对于我来说Java是最佳的选择工具,但任何其他解决方案(包括命令行工具或桌面软件)都是可以接受的。

+0

你想要做哪些转换?有些可以通过移动窗口来完成,所以你不需要全部加载。其他人可能会允许流式传输,有些可能需要所有的:) – extraneon 2010-08-11 15:38:40

+0

没有什么严重的,分裂成瓦片,或转换为更多压缩格式 – Ovesh 2010-08-11 17:55:50

根据this,应该合理地表明您可以使用它是行包装的事实。您应该能够读取部分行,存储它,前进到下一行中的相同位置并重复,直到完成所需大小的图块。很明显,如果您可以一次存储整行内存块,那么您可以一次执行多个切片。

没有必要一次加载多于文件头。标题格式在链接的*条目中描述。这可能是值得关注任何压缩方案正在使用 - 压缩可能使这项任务有点困难(虽然仍然不是不可能):)

不确定2011年这个任务,但Java 7(可能6 )有这样的乐趣很好的方法。

使用ImageReader和ImageReadParam类,它们允许在需要时读取源图像的​​任何矩形部分。设置源矩形和阅读

... // initialization 

private javax.imageio.ImageReadParam m_params; 
private javax.imageio.ImageReader m_reader; 

... // reading 

m_params.setSourceRegion(readRect); 
BufferedImage rdImg = m_reader.read(i, m_params); 

... // processing/displaying etc 

为BMP(它也能工作于任何标准的Java图像类型)是没有经过任何压缩非常平的格式在99.99%的情况下,阅读它的任何部分这样的方式是低非常快的过程内存消耗除了导致BufferedImage。或者,您甚至可以重复使用之前的BufferedImage,并以相同尺寸的矩形作为后续请求。请参阅ImageReadParam.setDestination(BufferedImage目标)。但我没有测试这个选项。

另外我发现了一个小的读取错误,即在Java运行库的BMP读者类实现中。如果有人对此感兴趣,我将展示简单的方法来纠正它。