0

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
Martin Mucha
  • 2,385
  • 1
  • 29
  • 49
  • 1
    Just to be sure, you know about https://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java ?! So why not SHOW us an example code with poor performance? Honestly, your question reads like a request by a 1-day newbie. You should really know better that people need more information in order to help you. – GhostCat Mar 11 '22 at 12:45
  • @GhostCat maybe I am actually a newbie. Yes, I know how to write microbenchmarks, but there is nothing to microbenchmark. I'm reading file using `javax.imageio.ImageIO#read(java.io.File)` for 6M file it takes more than 4s to complete. I tried to disable caching as recommended, not helped. So minimal example is: find any 10MB JPEG file, call this method. If you need more info, please just ask. – Martin Mucha Mar 11 '22 at 12:50
  • @GhostCat my file: JPEG image data, JFIF standard 1.01, resolution (DPI), density 72x72, segment length 16, Exif Standard: [TIFF image data, little-endian, direntries=10, xresolution=152, yresolution=160, resolutionunit=2, progressive, precision 8, 4032x3024, components 3 – Martin Mucha Mar 11 '22 at 12:53
  • 2
    Please: don't provide such information in **comments**. Instead, always [edit] your question. Don't expect readers to go through the (potentially many) comments below a question in order to help you. – GhostCat Mar 11 '22 at 13:00
  • 1
    And well, there is benchmarking here. Are you measuring the loading/display of a image within a RUNNING application? Or are you doing a `java my.whatever.App image.jpeg?`, just measuring the raw time until some frame with the image shows up? Stuff like that makes a HUGE difference. – GhostCat Mar 11 '22 at 13:02
  • I've not performed microbenchmarks on this, but I noticed that image reads (well under 10MB) for my specific home PC setup were generally quicker if reading into byte[] first - see these [comments](https://stackoverflow.com/questions/62852645/efficient-way-to-read-an-image-file-using-java/62862626#62862626). – DuncG Mar 11 '22 at 16:29
  • @DuncG thanks for tip! I have ssd, so as your link suggest it probably does not apply, but I tried it anywas, via `ImageIO.read(this.getClass().getResourceAsStream()) which produced slightly better performance than reading from file, and I also try to dump input stream into byte array and then wrap it into ByteArrayInputStream which I fed into ImageIO.read. These 2 and reading directly from file has similar performance on my ssd drive, all within 200ms difference. Meaning not notable/sufficient improvement. Difference between these 3 are probably just 'scheduler noise'. – Martin Mucha Mar 11 '22 at 21:37
  • My guess is that this specific JPEG is progressive. For some reasons, the ImageIO JPEG plugin is super-slow reading progressive JPEG, even if you don't need any progressive updates.... – Harald K Mar 12 '22 at 15:36
  • @HaraldK I've updated the question, I believe you are correct. If I understand the output correctly, it's progressive jpeg. – Martin Mucha Mar 13 '22 at 07:12

1 Answers1

1

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.

Lunatic
  • 1,519
  • 8
  • 24
  • Thank you again. just quick: `new ImagePlus("file.jpg").getBufferedImage();` yield 1.6 times faster loading times. Still not great result, but for effort this minimal it's a nice start. I need to read more into parallel loading. Thanks. – Martin Mucha Mar 11 '22 at 13:15
  • @MartinMucha Yeah investigate the multithread implementation in mentioned article .You are very welcome ! I appreciate any answer approval or upvote . – Lunatic Mar 11 '22 at 13:31
  • 1
    upvoted(sorry, I forgot), and if there isn't better answer, you will win ;) Will test multithreaded impl and update either with comment of edit to question. – Martin Mucha Mar 11 '22 at 13:35
  • 1
    note: NIH here, doesn't mean Not Invented Here, but National Institutes of Health, i.e. medical imaging ;) – Christoph Rackwitz Mar 11 '22 at 15:05
  • @ChristophRackwitz indeed :) – Lunatic Mar 11 '22 at 15:08