Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
758 views
in Technique[技术] by (71.8m points)

java - Write swing component to large TIFF image using JAI

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...