java - images - Convert BufferedImage into byte[] without I/O




turn byte array into image java (3)

Hi I have a BufferedImage instance in memory and want to convert it into byte[] to encode as base64 string without I/O operation for performance consideration. I was using the following API:

ByteArrayOutputStream baos = new ByteArrayOutputStream ();
ImageIO.write(image,"png",baos);
return baos.toByteArray();

However, this API still implicitly writes the image to the OS temp directory, which will lead to failure in case that the underlying OS temp directory is full and the temp file cannot be created. Stack Trace:

Caused by: java.io.IOException: No space left on device
    at java.io.RandomAccessFile.write(RandomAccessFile.java:493)
    at javax.imageio.stream.FileCacheImageOutputStream.write(FileCacheImageOutputStream.java:134)
    at javax.imageio.stream.ImageOutputStreamImpl.write(ImageOutputStreamImpl.java:66)
    at com.sun.imageio.plugins.png.PNGImageWriter.write_magic(PNGImageWriter.java:376)
    at com.sun.imageio.plugins.png.PNGImageWriter.write(PNGImageWriter.java:1115)
    at javax.imageio.ImageWriter.write(ImageWriter.java:628)
    at javax.imageio.ImageIO.write(ImageIO.java:1480)
    at javax.imageio.ImageIO.write(ImageIO.java:1554)

Is there an efficient (like in-memory conversion or efficient I/O) way to do the conversion without I/O? Please advise.

https://code.i-harness.com


((DataBufferByte)img.getRaster().getDataBuffer()).getData() automatically returns a byte array if your image was in a byte format. No need for any IO at all.


Both mentions of ImageIO.setUseCache(false) is correct. However, if you don't like to disable disk caching for ImageIO globally, an alternative is to explicitly wrap the stream in a MemoryCacheImageOutputStream (which does in-memory caching instead of disk caching):

ByteArrayOutputStream baos = new ByteArrayOutputStream ();
ImageOutputStream stream = new MemoryCacheImageOutputStream(baos);
ImageIO.write(image, "png", stream);
stream.close();
return baos.toByteArray();

ImageIO by default writes it's cache to disk even when you only use streams. Try disabling the cache with:

ImageIO.setUseCache(false);




in-memory