【问题标题】:Write swing component to large TIFF image using JAI使用 JAI 将 swing 组件写入大型 TIFF 图像
【发布时间】:2011-05-12 18:11:56
【问题描述】:

我有一个大的摆动组件要写入 TIFF。该组件太大而无法将 TIFF 加载到内存中,因此我要么需要制作一个由基于磁盘的 WritableRaster 支持的大 BufferedImage(如 here 所述),要么使用 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 而无需将整个内容加载到内存中?

【问题讨论】:

    标签: java swing tiff jai


    【解决方案1】:

    我必须使用 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(压缩)的图像,对于更大的图像我还没有测试过。

    但如果您使用的是 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);
    

    【讨论】:

    • 如何创建 TiledImage?
    • 我在上面添加了 TiledImage 创建。我将样本直接设置在图像中,因为我必须从源中逐个像素地加载像素。所以我在加载时总是在内存中保留一个图块。
    【解决方案2】:

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

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

    【讨论】:

    • 谢谢,D1i,我正在尝试将一个非常大的图像写入磁盘。我无法创建足够大的 BufferedImage,因为内存不足。最终的图像,我真的想要 10000 像素宽。
    • 我明白了,然后我误解了这个问题;O。我也期待着回答,看起来很有用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-26
    • 2017-02-22
    • 1970-01-01
    • 2013-11-10
    相关资源
    最近更新 更多