Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Byte array to buffered image conversion slow

I have a simple server-side code that receives a byte array representing an image in JPEG format and returns the dimensions of the image.

public String processImage(byte[] data) {
    long startTime = System.currentTimeMillis();
    ByteArrayInputStream stream = new ByteArrayInputStream(data);
    BufferedImage bufferedImage;
    bufferedImage = ImageIO.read(stream);

    int height = bufferedImage.getHeight();
    int width = bufferedImage.getWidth();

    long endTime = System.currentTimeMillis();

    return "height="+height+" | width="+width+" | elapsed="+(endTime-startTime);
}

It works, but the problem is it's unacceptably slow. For an image that's 100KB, it's taking 6s. For an image that's 900KB, it's taking 30s. Is that expected? Is there a way to make byte array to bufferedImage conversion faster?

FYI, grabbing height/width isn't the only thing I intend to do. I eventually want to process the bufferedImage. So getting height/width was just an example code.

like image 451
baekacaek Avatar asked Nov 21 '13 22:11

baekacaek


2 Answers

I think the problem might be related to the fact that ImageIO by default uses disk caching (to a temp file), even if your source is a ByteArrayInputStream. So if your file system is slow, reading will also be slow, regardless of input source.

You can disable the disk caching (at the cost of using more memory) with ImageIO.setUseCache(false). This will still cache your streams (to allow backwards seeking), but only in memory.

It's also possible to set the cache directory to a specific path using ImageIO.setCacheDirectory(cacheDirectory), if you have a faster disk/ramdisk or similar to store your temp files.

That said, your reported read times seems unreasonably high, even for disk cached reads. If the problem persists, I suggest using a profiler to find out where the time is spent, and look at possible optimizations.

PS: I also have a custom ByteArrayImageInputStream that might help reduce both disk access and memory consumption, should this really be the problem.

like image 170
Harald K Avatar answered Sep 30 '22 12:09

Harald K


From where are you reading the image? From where comes the byte[]? If you're reading the image from a hdd it maybe would help to read it by using a BufferedInputStream.

This can speed loading up. But this helps only if you're reading from a FileInputStream for example. When reading from the ByteArrayInputStream it won't help.

EDIT: Is there maybe more information you could give us? Where the byte array comes from?

like image 33
maxammann Avatar answered Sep 30 '22 12:09

maxammann