I work with extremely large tif images that I compose in a large single image. I have a library created by my colleague that generates a pyramid of images and provides a very convenient tool for visualizing a pyramid of images. This visualizer is great for picking out a peak in a large image and visually identifying points of interest, but customers are more interested in analyzing the images in these large images.
Thus, it is necessary to export a very large image into a single file. I find this to be unpleasant given that these images can range from 800 MB to several GB. And the task of loading this single image into memory is complicated, especially when image analysis is performed.
I was wondering if it would be possible in java to write this large tiff image in a block or in turn. My app currently runs out of memory on small (8 GB RAM) machines.
The current method of compiling these images is:
Save pixel values ββin BufferedImage with WritableRaster
short[][]pixels = ... BufferedImage image = new BufferedImage(width, height, type); WritableRaster = image.getRaster(); for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { raster.setSample(col, row, 0, pixel[row][col]); } }
Then write the buffer image to disk. For this part, I use ImageJ to write the image as tif. If there are more efficient ways to support 16-bit grayscale images, then Iβm happy to see
// BufferedImage image; from above ... ImagePlus img = new ImagePlus(); img.setImage(image); FileSaver fs = new FileSaver(img); fs.saveAsTiff(file.getAbsolutePath());
The problem with this method is that it has too much memory for 8 GB of RAM.
Ideally, I would like for me to have only one short[][]pixels . This is mainly because I need to calculate the average mixing function, so there will be some amount of memory. Also in the future I will add a linear mixture. short[][]pixels should only accept ~ 765 MB of RAM for 20 kg pixel data, which I think is currently unavoidable, so for large images like 100k x 100k pixels, I hope that biologists donβt want to export this one since it takes 18 GB of RAM.
Later, I will modify the code to support the export of extremely large images such as 100k x 100k. So far, I agree with the assumption that one piece of memory will retain the initial pixel values.
So, which is a good method for writing portions of a tif image to disk, so I can support writing from basic images such as 100k x 100k images.
I saw this post: Write TILF output using ImageIO in Java
But he just discusses the TIFF 6.0 specification. But I will consider ImageOutputStreams . Tif is a beast, although I can just bite a bullet and encourage biologists to export only regions of interest.
EDIT: Viable solution found:
WRITER: https://github.com/openmicroscopy/bioformats/blob/v4.4.8/components/scifio/src/loci/formats/out/TiffWriter.java
and
READER: https://github.com/openmicroscopy/bioformats/blob/v4.4.8/components/scifio/src/loci/formats/in/TiffReader.java
Group homepage: https://github.com/openmicroscopy/bioformats