4

What I have is a a large number of frames that need to be placed together in a larger image (like a mosaic). The required positions of the images are known.

There are a very large number of images so loading them all into memory is impractical at best.

Based on some other answers here I was able to override the methods in RenderedImage (specifically getData(rect)) to load in the appropriate data and return it.

This works just fine, however the image writer is always calling getData and requesting rows of data. It seems to me I should be able to change the ImageWriterParam to call for individual tiles instead, but when I tried the write function still calls for a single line from getData.

How can I force this to use tiles and call getTile instead.

BufferedOutputStream bos=null;
try {
   bos = new BufferedOutputStream(new FileOutputStream(new File("test2.tiff")));

   ImageWriter writer =(ImageWriter) ImageIO.getImageWritersBySuffix("tif").next();

   ImageOutputStream ios=null

   ios = ImageIO.createImageOutputStream(bos); 

   writer.setOutput(ios);
   ImageWriteParam param = writer.getDefaultWriteParam();
   param.setTilingMode(ImageWriteParam.MODE_DEFAULT);

   RenderedImage mosaic = new MosaicImage(imageFiles[]);

   writer.write(null,new IIOImage(mosaic,null,null),param);

    } catch (FileNotFoundException ex) {

    }

Note I can use param.setTilingMode(ImageWriteParam.MODE_EXPLICIT); and setTiling(w,h,xoff,yoff);

However when using this, writer.write still calls getData(rect) in my image, and very annoyingly does not call for a rectangle of the size specified by w,h. It calls a rectangle of a size that is different by some random amount(probably comes from something)

For example if I use setTiling(100,100,0,0);

one would expect that even if it does not call getTile from the image, the Rectangle passed to getData should be (0,0,100,100) but instead it passes Rectangle (0,0,96,96) which is not a multiple of the image width or anything else i can think of.

Thanks for any help

Perception
  • 79,279
  • 19
  • 185
  • 195
David
  • 133
  • 1
  • 2
  • 5

1 Answers1

4

If you read up on the TIFF 6.0 spec under the TileWidth and TileLength fields, you will find the text

TileWidth must be a multiple of 16. This restriction improves performance in some graphics environments and enhances compatibility with compression schemes such as JPEG.

And similar for TileLength. 100x100 isn't divisible by 16, but 96x96 is, which I bet is the TIFF encoder trying its best to fullfill your request.

Justin Aquadro
  • 2,280
  • 3
  • 21
  • 31
  • Wow, great detective work, this explains the odd behavior that I am seeing. It also unfortunately means that I cannot write my mosaic by tile as I had hoped, but thank you for you help. – David Mar 06 '12 at 17:58
  • The right and bottom edge tiles are assumed to be padded if they don't fit. In other words, it's not a problem that your image size isn't an exact multiple of your tile size. If you have a 645x645 image with a tile size of 128x128, you will have 6x6 tiles encoded in the file and some wasted space, but it's perfectly valid. – BitBank Mar 12 '12 at 02:05