3

So I'm trying to get a PNG image from stream.

image = ImageIO.read(inputStream);

And this code is running for ten seconds! I thought the problem was in slow InputStream, so I tried to load it in buffer first.

byte[] bytes = inputStreamToBytes(inputStream);
image = ImageIO.read(new ByteArrayInputStream(bytes));

And guess what! It takes about 100ms to load it from InputStream to buffer, but hell of a lot of time just to read it from byte array! A ten (TEN) seconds to read! From a RAM!

I'm doing it on Raspberry PI. And yes, I understand it's a toy, not a real computer. So I tried to do it on my MacBook Air. Really, two seconds are better then ten. But still a lot for some 800x600 PNG. So why it so? And what to do?

user1748526
  • 464
  • 5
  • 18
  • Java's ImageIO is just flat out slow for everyone... I doubt you are doing anything wrong. – John Newman Nov 07 '16 at 15:15
  • 3
    ^ That is a bold statement. However, can you provide (upload) the file that you are trying to load? It seems to be somewhat specific, but to verify this: Is it so slow for every arbitrary, random, 800x600 image, or only for this particular one? (Maybe it has some odd, unusual format, compression type or so...) – Marco13 Nov 07 '16 at 15:20
  • 3
    @Marco13 ImageIO does have a reputation for being inexplicably slow, even after examining the source code. – chrylis -cautiouslyoptimistic- Nov 07 '16 at 15:28
  • It's a screenshot from "adb shell screencap -p" – user1748526 Nov 07 '16 at 18:17
  • 1
    You are doing it wrong. ;-) ImageIO is using a disk cache by default, even if reading from an in-memory input stream... Try using [`ImageIO.setUseCache(false)`](https://docs.oracle.com/javase/7/docs/api/javax/imageio/ImageIO.html#setUseCache(boolean)) to get a "free" speed improvement. – Harald K Nov 07 '16 at 18:38
  • ImageIO.setUseCache(false) didn't help :( – user1748526 Nov 08 '16 at 16:14
  • Possible duplicate: http://stackoverflow.com/questions/20132911/byte-array-to-buffered-image-conversion-slow – Harald K Nov 14 '16 at 08:00

1 Answers1

1

You probably need to install Java Native IO libraries they are not installed by default.

http://www.oracle.com/technetwork/java/install-jai-imageio-1-0-01-139659.html

If you don't have this lib installed all operations on images are performed in java not natively.

Greg
  • 1,671
  • 2
  • 15
  • 30
  • While JAI (with native codecs, like libpng in this case) may help in some cases, I doubt JAI comes with prebuilt native binaries for Raspberry Pi. JAI hasn't been developed for several years. Creating your own JNI interface for libpng is likely a better option. – Harald K Nov 07 '16 at 18:49
  • Does OpenJDK contain native IO? – user1748526 Nov 08 '16 at 16:15
  • @user1748526 JPEG encoding/decoding uses native code (libJPEG). Not native for anything else. AFAIK. – Harald K May 31 '21 at 10:53