开发者

Write swing component to large TIFF image using JAI

I have a large swing c开发者_开发知识库omponent 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?


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


I had the same situation and I used these steps:

  • Load as BufferedImage with JAI

  • Resize BufferedImage size to preferable size (600x600px) maintaining aspect-ratio using Image#getScaledInstance(int w, int h, Image.SCALE_SMOOTH)

  • Draw image using Graphics2d.drawImage(..) method in JComponent#paintComponent(java.awt.Graphics) method

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜