我正在处理我正在组合成一个大的单个图像的非常大的 tif 图像。我有一个由我的同事创建的库,它生成图像金字塔并提供了一个非常方便的工具来可视化图像金字塔。该可视化器非常适合在大图像上获取峰值并在视觉上识别兴趣点,但客户对这些大图像的图像分析更感兴趣。
因此,有必要将非常大的图像导出到单个文件中。考虑到这些图像的大小可以从 800 MB 到数 GB 不等,我觉得这很麻烦。仅将单个图像加载到内存的任务就具有挑战性,尤其是在进行图像分析时。
我想知道,是否可以在 java 中以块或逐行的方式编写这个大的 tiff 图像。目前,我的应用程序在小型(8 GB RAM)机器上内存不足。
构成这些图像的当前方法是:
BufferedImage
使用 a将像素值存储到aWritableRaster
short[][]pixels = ... BufferedImage image = new BufferedImage(width, height, type); WritableRaster = image.getRaster(); for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { raster.setSample(col, row, 0, pixel[row][col]); } }
然后将缓冲的图像写入磁盘。对于这一部分,我使用
ImageJ
将图像写为 tif。如果有更好的方法支持 16 位灰度 tif 图像,那我很乐意去看看// BufferedImage image; from above ... ImagePlus img = new ImagePlus(); img.setImage(image); FileSaver fs = new FileSaver(img); fs.saveAsTiff(file.getAbsolutePath());
这种方法的问题是它对于 8GB RAM 机器的内存占用太大。
理想情况下,我想要的是只有一个short[][]pixels
. 这主要是因为我需要计算一个平均混合函数,所以会有一些内存占用。同样在未来我将添加一个线性混合。对于short[][]pixels
20k x 20k 像素数据,应该只占用约 765 MB 的 RAM,我认为这目前是不可避免的,因此对于较大的图像,例如 100k x 100k 像素,我希望生物学家不会想要导出这个图像,因为它将占用 18GB 的 RAM。
稍后我将修改代码以支持导出 100k x 100k 等超大图像。现在我可以假设一块内存来存储初始像素值。
那么,将 tif 图像的一部分写入磁盘的好方法是什么,以便我可以支持写出核心图像,例如 100k x 100k 图像。
我确实看到了这篇文章:Write tiled output of TIFF, using ImageIO in Java
但它只是讨论了 TIFF 6.0 规范。但我会调查ImageOutputStreams
。Tif 是一头野兽,所以我可能只是硬着头皮鼓励生物学家只导出感兴趣的区域。
编辑:找到一个可行的解决方案:
和