我正在尝试在一组非常大(几GB)的BMP图像文件上进行一些操作(特别是转换为不同类型的切换到切片)。
我不确定我是否理解BMP文件格式,但是有必要将整个文件加载到内存中吗?我无法找到任何不需要在某个时刻加载整个文件的API。 ImageMagick也无法做到。
Java对我来说是最好的选择工具,但任何其他解决方案,包括命令行工具或桌面软件都是可以接受的。
答案 0 :(得分:2)
基于this,你应该可以理解它可以使用它是行包装的事实。您应该能够读取行的一部分,存储它,前进到下一行中的相同位置并重复,直到您完成了所需大小的图块。显然,如果你可以一次性将整行的瓷砖存储在内存中,你可以一次做多个瓷砖。
不必一次加载超过文件头的内容。标题格式在链接的维基百科条目中描述。它可能值得关注所使用的任何压缩方案 - 压缩可能会使这项任务变得更难(尽管仍然不是不可能):))
答案 1 :(得分:1)
不确定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阅读器类实现中。如果有人对此感兴趣,我会用简单的方法来纠正它。