51

How can I get an InputStream from a BufferedImage object? I tried this but ImageIO.createImageInputStream() always returns NULL

BufferedImage bigImage = GraphicsUtilities.createThumbnail(ImageIO.read(file), 300);
ImageInputStream bigInputStream = ImageIO.createImageInputStream(bigImage);

The image thumbnail is being correctly generated since I can paint bigImage to a JPanel with success.

İsmail Y.
  • 3,579
  • 5
  • 21
  • 29
lbrandao
  • 4,144
  • 4
  • 35
  • 43

3 Answers3

98

From http://usna86-techbits.blogspot.com/2010/01/inputstream-from-url-bufferedimage.html

It works very fine!

Here is how you can make an InputStream for a BufferedImage:

URL url = new URL("http://www.google.com/intl/en_ALL/images/logo.gif");
BufferedImage image = ImageIO.read(url);
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(image, "gif", os);
InputStream is = new ByteArrayInputStream(os.toByteArray());
Felipe
  • 16,649
  • 11
  • 68
  • 92
  • Felipe. I was trying to find the type(gif, png, jpg, etc) of an image that came from a URL without an extension. I found a work around for it but when you write the image to an input stream ImageIO.write(image,'gif',os); you have already mentioned the image type, how can I do that without specifying the image type. – WowBow May 01 '15 at 18:35
  • You have to specify a type. I guess it shoulnd't be the same as the input. You can read from a PNG and write on a JPEG. – Felipe May 01 '15 at 19:43
  • 3
    Won't this duplicate the data not just once but twice? First when ImageIO.write writes it to a ByteArrayOutputStream and then again when toByteArray() is called. This is not just a memory hit but also CPU hit. – morpheus May 20 '16 at 17:27
  • @morpheus what you say makes sense, so then what is the actual sensible approach ? – Lorenzo Jun 30 '20 at 17:10
13

If you are trying to save the image to a file try:

ImageIO.write(thumb, "jpeg", new File(....));

If you just want at the bytes try doing the write call but pass it a ByteArrayOutputStream which you can then get the byte array out of and do with it what you want.

TofuBeer
  • 60,850
  • 18
  • 118
  • 163
  • 2
    Thanks, writing to ByteArrayOutputStream and then converting it to a ByteArrayInputStream did the job. But I'm wondering why ImageIO.createImageInputStream() didn't work. – lbrandao Mar 16 '09 at 04:16
  • It looks like that expects the Object passed in to be a File (or perhaps other things). I haven't used the API before... and not sure what it is you are trying to do :-) (consider it a lucky guess on my part that what I gave you worked :-) – TofuBeer Mar 16 '09 at 04:22
  • I'm trying to upload the image to a server, that's why I want to create an InputStream from it. – lbrandao Mar 16 '09 at 04:24
  • Ah, look at http://java.sun.com/j2se/1.5.0/docs/api/javax/imageio/ImageIO.html#createImageInputStream(java.lang.Object) input - an Object to be used as an input source, such as a File, readable RandomAccessFile, or InputStream. – TofuBeer Mar 16 '09 at 04:29
8

By overriding the method toByteArray(), returning the buf itself (not copying), you can avoid memory related problems. This will share the same array, not creating another of the correct size. The important thing is to use the size() method in order to control the number of valid bytes into the array.

final ByteArrayOutputStream output = new ByteArrayOutputStream() {
    @Override
    public synchronized byte[] toByteArray() {
        return this.buf;
    }
};
ImageIO.write(image, "png", output);
return new ByteArrayInputStream(output.toByteArray(), 0, output.size());
Mysticial
  • 464,885
  • 45
  • 335
  • 332
Igor
  • 129
  • 1
  • 2
  • Doing this and using `IOUtils.copy(is, output)` the `buf` results in double size. So it seems a very bad approach. I should downvote but I can't anymore. – Davideas May 12 '17 at 14:52