How to read JPEG into BufferedImage efficiently in java

448 views Asked by At

ImageIO.read reads the file into BufferedImage at least 200 times slower, that other programs like feh can read the file and render it on screen. What can you use instead of ImageIO or how to configure ImageIO, so that it reads the data in reasonable timeframe?

EDIT how do I load/measure.

    long start = System.nanoTime();
    ImageIO.setUseCache(false);
    try {
        ImageIO.read(new URL("file:///tmp/reallyBig.jpg"));
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
    end = System.nanoTime();
    System.out.println("duration: "+ TimeUnit.NANOSECONDS.toMillis(end-start)));

yes, it's not precise, because I didn't do warmups etc. etc. But this won't do 200ms from 4000ms, so I can live with this imprecision. I need not to know exactly how fast it is in us precision, I can see it's really slow without any measuring needed. I actually don't need situation, that it eventually get 5ms faster after 10k iterations, I really need to see the normal waiting times upon user request from running application. And again, this image can be rendered by feh in 200ms, while it's not loaded into BufferedImage by ImageIO in 4000ms.

Trivially replacing ImageIO.read with new ImagePlus(...).getBufferedImage(); yields 1.6x speed up. Need to actually read documentation to get better results with ImageJ.

If someone know how to get better results in different way, please share.

EDIT 2: what is this image(severely shortened):

identify -verbose fullImage.jpg
Image:
  Format: JPEG (Joint Photographic Experts Group JFIF format)
  Mime type: image/jpeg
  Class: DirectClass
  Geometry: 4032x3024+0+0
  Resolution: 72x72
  Print size: 56x42
  Units: PixelsPerInch
  Colorspace: sRGB
  Type: TrueColor
  Base type: Undefined
  Endianness: Undefined
  Depth: 8-bit
  Interlace: JPEG
  Intensity: Undefined
  Compose: Over
  Page geometry: 4032x3024+0+0
  Dispose: Undefined
  Iterations: 0
  Compression: JPEG
  Quality: 100
  Orientation: TopLeft
  Profiles:
    Profile-exif: 12424 bytes
    Profile-icc: 672 bytes
    Profile-xmp: 3160 bytes
  Filesize: 5.65549MiB
  Number pixels: 12.1928M
1

There are 1 answers

5
Lunatic On

ImageJ is a public domain Java image processing program inspired by NIH, It is multithreaded and works way faster than ImageIo implementation in Buffering, so time-consuming operations such as image file reading can be performed in parallel, more sepecificly the ij.io package contains classes for reading/decoding and writing/encoding images which you can investigate the implementation of converting files to bufferImages.