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

发布于 2024-11-06 15:16:09 字数 865 浏览 7 评论 0原文

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

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

鉴于此,有人可以概述在不耗尽内存的情况下将我的 swing 组件写入平铺 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,但只能从光栅或缓冲图像创建,而我没有足够的内存。

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

I have a large swing component to write to TIFF. The component is too large to load the TIFF in memory, so I either need to make a big BufferedImage which is backed by a disk-based WritableRaster (as mentioned here) or use JAI.

JAI seems like the better answer, aside from the utter confusion of the project.

Given that, can someone outline steps for writing my swing component to a tiled TIFF without running out of Memory?

Image size will be maybe 10000x700

Ideally I would create some sort of disk-based image, and write parts of the component to it, each write being flushed to disk.

EDIT

I think I could do this with an ImageWriter, however I'm getting a NoSuchElementException when I call:

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

I have the jai_code.jar and jai_core.jar jars on my classpath, is there something else I need to do?

EDIT
I can create a very large TIFF using JAI, but JAI doesn't support TIFF compression, so the file is 92 MB.

If I install JAI-ImageIO, I can create a compressed TIFF Using an ImageWriter, but only from a Raster or BufferedImage, which I don't have enough memory for.

Is there some way to do a two-step approach, use JAI to create the large TIFF, then compress the large TIFF without loading the whole thing into memory?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦旅人picnic 2024-11-13 15:16:09

我必须使用 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);

I had to load and store a large tiff (59392x40192px) with JAI. My solution is: TiledImages.

I have used a TiledImage because I need tiles and subimages.
To use the TiledImage efficient you should construct it with your prefered tile size. JAI uses a TileCache so not the whole Image will be in memory, when it's not needed.

To write the TiledImage in a File use the option "writeTiled" (avoid OutOfMemory because it writes tile by tile):

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);
}

It works fine with images up to 690mb (compressed), for larger images i haven't tested yet.

But if you are working on WinXP 32-bit you may not able to have more as 1280m HeapSpace size, this is still a limit of Java VM.

My TiledImage is build with a IndexedColorModel from my image-source data:

//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);
梨涡少年 2024-11-13 15:16:09

我遇到了同样的情况,我使用了以下步骤:

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

I had the same situation and I used these steps:

That helped me with showing and manipulating TIFF images ~50MB (5000x5000px).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文