1

I have some code which uses the ImageReader class to read in a large number of TIF images. The imageReader object is final and created in the constructor.

synchronized(imageReader) {
    LOG.debug(file);
    FileInputStream fin = new FileInputStream(file);
    ImageInputStream iis = ImageIO.createImageInputStream(fin);
    imageReader.setInput(iis, false);
    int sourceXSubSampling = targetSize == null ?
            1 : Math.max(1, imageReader.getWidth(0) / targetSize.width);
    int sourceYSubSampling = targetSize == null ?
            1 : Math.max(1, imageReader.getHeight(0) / targetSize.height);
    ImageReadParam subSamplingParam = new ImageReadParam();
    subSamplingParam.setSourceSubsampling(sourceXSubSampling, sourceYSubSampling, 0, 0);
    return imageReader.read(0, subSamplingParam);
}

About one instance in four the ImageReader get "stuck" on the first image it loaded and keeps loading that same image over and over again even though it is provided with different ImageInputStreams. This is evidenced by the output to the logger.

How do I solve this. I was thinking about taking a "fingerprint" of the image and getting a different ImageReader from the iterator if this occurs but that seems like overkill. Does anyone know how to solve this problem?

James Robinson
  • 1,222
  • 1
  • 15
  • 43
  • 1
    1- Close your streams; 2- Dispose of the reader after you've finished reading; 3- Ask for a "new" reader each time. May not solve the problem, but isn't going to hurt... – MadProgrammer Aug 29 '13 at 21:59
  • Actually, you don't need the extra `FileInputStream`, just call `ImageIO.createImageInputStream(file)` directly. Then you don't have to close it, and it [may even be faster](http://stackoverflow.com/questions/18522398/fastest-way-to-read-write-images-from-a-file-into-abufferedimage/18534396#18534396) too. :-) – Harald K Aug 30 '13 at 14:50

1 Answers1

2

As @MadProgrammer says in the comment section, the typical pattern for reading multiple images is to obtain a new ImageReader for each image, and afterwards dispose() it. The time/memory spent on creating a reader instance is very small, compared to actually reading an image. So any performance penalty should be negligible.

In theory it should, however, be sufficient to invoke reset() on the ImageReader before/after each read.

Harald K
  • 26,314
  • 7
  • 65
  • 111