Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert BufferedImage into byte[] without I/O

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.

like image 345
user1344933 Avatar asked Apr 19 '12 19:04

user1344933


People also ask

How to convert BufferedImage into byte array in Java?

This article shows how to convert a BufferedImage to a byte array or byte[] . BufferedImage bi = ImageIO. read(new File("c:\\image\\mypic. jpg")); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.

How do you write BufferedImage?

The formatName parameter selects the image format in which to save the BufferedImage . try { // retrieve image BufferedImage bi = getMyImage(); File outputfile = new File("saved. png"); ImageIO. write(bi, "png", outputfile); } catch (IOException e) { ... }

What kind of exception does the ImageIO class cause?

imageio. ImageIO. write and that failure is causing a null pointer exception.


3 Answers

Disable the ImageIO cache through the ImageIO.setUseCache() method:

ImageIO.setUseCache(false);

It is on by default according to the javadoc:

Sets a flag indicating whether a disk-based cache file should be used when creating ImageInputStreams and ImageOutputStreams.

When reading from a standard InputStream>, it may be necessary to save previously read information in a cache since the underlying stream does not allow data to be re-read. Similarly, when writing to a standard OutputStream, a cache may be used to allow a previously written value to be changed before flushing it to the final destination.

The cache may reside in main memory or on disk. Setting this flag to false disallows the use of disk for future streams, which may be advantageous when working with small images, as the overhead of creating and destroying files is removed.

On startup, the value is set to true.

like image 116
prunge Avatar answered Oct 21 '22 09:10

prunge


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();
like image 36
Harald K Avatar answered Oct 21 '22 08:10

Harald K


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

ImageIO.setUseCache(false);
like image 43
Roger Lindsjö Avatar answered Oct 21 '22 09:10

Roger Lindsjö