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 dis
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).