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.
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.
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With