使用JAI将swing组件写入大TIFF图像

时间:2011-05-12 18:11:57

标签: java swing tiff jai

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

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

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

图像大小可能是10000x700

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

修改

我想我可以使用ImageWriter执行此操作,但是当我调用时,我收到NoSuchElementException:

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

我的classpath上有jai_code.jar和jai_core.jar jar,还有什么我需要做的吗?

修改 我可以使用JAI创建一个非常大的TIFF,但是JAI不支持TIFF压缩,所以文件是92 MB。

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

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

2 个答案:

答案 0 :(得分:2)

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

我使用了TiledImage,因为我需要tile和subimages。 要使用TiledImage效率,您应该使用您喜欢的磁贴大小来构建它。 JAI使用TileCache,因此当不需要时,不会将整个Image放在内存中。

要在文件中写入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(压缩)的图像,它可以正常工作,对于我尚未测试过的较大图像。

但是,如果你正在使用32位WinXP,你可能无法获得更多的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);

答案 1 :(得分:1)

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

这帮助我显示和操作TIFF图像~50MB(5000x5000px)。