3

我有一个大的摆动组件要写入 TIFF。该组件太大而无法将 TIFF 加载到内存中,因此我要么需要制作一个由基于磁盘的 WritableRaster 支持的大 BufferedImage(如此所述),要么使用 JAI。

除了项目的完全混乱之外,JAI 似乎是更好的答案。

鉴于此,有人可以概述将我的挥杆组件写入平铺 TIFF 而不会耗尽内存的步骤吗?

图像尺寸可能为 10000x700

理想情况下,我会创建某种基于磁盘的映像,并将部分组件写入其中,每次写入都会刷新到磁盘。

编辑

我想我可以用 ImageWriter 做到这一点,但是当我打电话时我得到了 NoSuchElementException:

ImageWriter imageWriter = ImageIO.getImageWritersByFormatName("tif").next();

我的类路径上有 jai_code.jar 和 jai_core.jar jar,我还需要做些什么吗?

编辑 我可以使用 JAI 创建一个非常大的 TIFF,但 JAI 不支持 TIFF 压缩,因此文件为 92 MB。

如果我安装 JAI-ImageIO,我可以使用 ImageWriter 创建一个压缩的 TIFF,但只能从我没有足够内存的 Raster 或 BufferedImage 创建。

有没有办法做一个两步的方法,使用 JAI 创建大 TIFF,然后压缩大 TIFF 而不将整个东西加载到内存中?

4

2 回答 2

2

我不得不用 JAI 加载和存储一个大的 tiff (59392x40192px)。我的解决方案是:TiledImages。

我使用了 TiledImage,因为我需要瓷砖和子图像。要高效使用 TiledImage,您应该使用您喜欢的图块大小来构建它。JAI 使用 TileCache,因此当不需要时,整个图像不会在内存中。

要在文件中写入 TiledImage,请使用选项“writeTiled”(避免 OutOfMemory,因为它逐块写入):

public void storeImage(TiledImage img, String filepath) {
    TIFFEncodeParam tep = new TIFFEncodeParam();
    //important to avoid OutOfMemory
    tep.setTileSize(256, 256);
    tep.setWriteTiled(true);
    //fast compression
    tep.setCompression(TIFFEncodeParam.COMPRESSION_PACKBITS);
    //write file
    JAI.create("filestore", img, filepath, "TIFF", tep);
}

它适用于高达 690mb(压缩)的图像,对于更大的图像我还没有测试过。

但是如果你在 WinXP 32 位上工作,你可能无法拥有更多 1280m 的 HeapSpace 大小,这仍然是 Java VM 的限制。

我的 TiledImage 是使用来自我的图像源数据的 IndexedColorModel 构建的:

//here you create a ColorModel for your Image
ColorModel cm = source.createColorModel();
//then create a compatible SampleModel, with the tilesize
SampleModel sm = cm.createCompatibleSampleModel(tileWidth,tileHeight);

TiledImage image = new TiledImage(0, 0, imageWidth, imageHeight, 0, 0, sm, cm);
于 2011-06-16T11:37:00.103 回答
1

我有同样的情况,我使用了这些步骤:

这有助于我显示和处理约 50MB (5000x5000px) 的 TIFF 图像。

于 2011-05-12T18:45:19.140 回答