Java- Convert bufferedimage to byte[] without writing to disk

44,370

Solution 1

This should work:

byte[] imageBytes = ((DataBufferByte) bufferedImage.getData().getDataBuffer()).getData();

Solution 2

The code below it's really fast (few milliseconds)

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

public byte[] toByteArray(BufferedImage image) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();            
    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(baos);
    encoder.encode(image);            
    return baos.toByteArray();
}

Solution 3

ByteArrayOutputStream baos;
ImageIO.write(bufferedImage, "png", baos);
byte[] imageBytes = baos.toByteArray();

Solution 4

Try using:

ImageIO.setUseCache(false);

Before writing, maybe that helps.

Solution 5

BufferedImage img = ImageIO.read(new ByteArrayInputStream(bytes));
byte[] bytes = new byte[buf.capacity()];
buf.get(bytes, 0, bytes.length);
Share:
44,370

Related videos on Youtube

tier1
Author by

tier1

Updated on July 20, 2020

Comments

  • tier1
    tier1 almost 4 years

    I'm trying to send multiple images over a socket using java but I need a faster way to convert the images to a byte array so I can send them. I tried the following code but it wrote about 10,000 images to my C:\ drive. Is there a way to make this conversion without writing to disk? Thanks!

    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    
                        //ImageIO.setUseCache(false);
                        ImageIO.write(bi.getImage(), "jpg", outputStream);
    
                        byte[] imageBytes = outputStream.toByteArray();
    
    • Andrew Thompson
      Andrew Thompson about 12 years
      Note that a little extra time doing the image compression using a higher compression (lower quality) JPEG can save a lot of network time. I think you need to consider the byte size actually sent, which will be significantly larger with a pure BufferedImage. BTW - what is the source of these images? If it is screenshots for e.g., often PNG can provide a smaller byte size than a default compression JPEG. If it were continuous screenshots, perhaps even a video stream.
    • tier1
      tier1 about 12 years
      The source is continuous screenshots that I'm essentially making into a stream. But yes, I need to figure out how to compress the images without writing them to disk. That is my ultimate goal
  • tier1
    tier1 about 12 years
    I tried this, however, I believe this still writes to disk, it just deletes it after the operation is complete.
  • soulcheck
    soulcheck about 12 years
    it shouldn't, at least according to docs : 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.. Maybe your program writes to disk somewhere else?
  • tier1
    tier1 about 12 years
    Yeah, I saw that in the docs as well. Either way, the operation is painfully slow for what I'm looking to do. Thanks though.
  • eCommerce Guru
    eCommerce Guru over 11 years
    This will create a copy of the image. If you just want a direct reference to the bytes, call bufferedImage.getRaster().getDataBuffer() and cast it accordingly (it's not always safe to cast to a DataBufferByte)
  • Richard
    Richard over 10 years
    AFAIU the setUseCache() flag only applies to input streams when reading an image from a stream. ImageIO either loads it into memory or moves it to a disk (when use cache = true), to support all kinds of random access operations normally not possible with InputStream. But the file format parsers (who operate on that ImageInputStream) will always create a BufferedImage as result, which will be completely in memory and uncompressed. Only Java Advanced Imaging has parsers to support tile based reading and conversion, without ever having to store the entire image in memory.
  • Erieze Lagera
    Erieze Lagera over 7 years
    It's better to stay away with com.sun package.
  • user3712476
    user3712476 over 7 years
    this doesn't seem to work for me. I get java.awt.image.DataBufferInt cannot be cast to java.awt.image.DataBufferByte my bufferedimage is coming from a Robot.createScreenCapture() not sure if that matters
  • stacker
    stacker over 7 years
    @user3712476 seems that Robot isn't a class from JRE libs, you could try to assign it to variable of type DataBufferInt and cast it to DataBufferInt .
  • Serġan
    Serġan almost 6 years
    Official post on why sun package should not be used: oracle.com/technetwork/java/faq-sun-packages-142232.html
  • meawoppl
    meawoppl almost 5 years
    Not an answer to the question.
  • Surabhi Mundra
    Surabhi Mundra over 4 years
    bufferedImage.getData().getDataBuffer() is creating invalid byte array for buffered image