2

I hope you guys can help me with this one. I'm not sure if it is a bug in Java or if I'm doing something wrong, but I'll go with the latter.

I want to turn a BufferedImage into a GIF image. I then wish to keep the GIF in the memory in the form of a byte array. (I do not want to save the file to disk)

The program should capture a screen segment (just to create a quick image) and turn it into a GIF byte array using ImageIO ImageWriter and ByteArrayOutputStream.

The code below will show you the bug. The program will crash and give an ArrayIndexOutOfBoundsException and the array remains empty. If you replace the "gif" with "png" it will work just fine, hence my confusion. Also! If I save the image to a file on disk with

write.setOutput(ImageIO.createImageOutputStream(new FileOutputStream(new File("C:/Image.gif"))); 

it will save it to a .gif file correctly.

So my question is, what did I do wrong in this patch of code? Any help will be greatly appreciated! :)

Note: This is not an animated GIF, no transparency involved either.

 String format = "gif"; Robot r = null; try { r = new Robot(); } catch (AWTException e1) { e1.printStackTrace(); } BufferedImage screen = r.createScreenCapture(new Rectangle(512,512)); final BufferedImage gif = new BufferedImage(512,512,BufferedImage.TYPE_BYTE_INDEXED); Graphics2D g = gif.createGraphics(); g.drawImage(screen,0,0,null); g.dispose(); ImageWriter write = ImageIO.getImageWritersBySuffix(format).next(); ByteArrayOutputStream out = new ByteArrayOutputStream(); try { write.setOutput(ImageIO.createImageOutputStream(out)); write.write(gif); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } for(int i=0; i < 10; i++) { System.out.println(out.toByteArray()[i]); } 
1
  • For better help sooner, post an SSCCE. Commented Jan 23, 2013 at 21:42

2 Answers 2

4

It seems there is some strange (if not plainly buggy) implementation of stream bufferings in com.sun.imageio.plugins.gif.*. If you don't flush or close explicitly the ImageOutputStream, the contents doesn't get flushed, even after closing the underlying stream. Change

 write.setOutput(ImageIO.createImageOutputStream(out)); write.write(gif); 

to

 ImageOutputStream imageos = ImageIO.createImageOutputStream(out); write.setOutput(imageos); write.write(gif); imageos.close(); // or imageos.flush(); 
Sign up to request clarification or add additional context in comments.

Comments

1

U have to use a ByteArrayOutputStream to get image as bytes. To write to this ByteArrayOutputStream, you should wrap it with an ImageOutputStream.

ImageWriter jpgWriter = ImageIO.getImageWritersByFormatName("gif").next(); //got imagewriter for gif ImageWriteParam gifWriteParam = jpgWriter.getDefaultWriteParam(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageOutputStream ios=ImageIO.createImageOutputStream(baos); jpgWriter.setOutput(ios); jpgWriter.write(null,new IIOImage(myBufferedImageObject, null, null),gifWriteParam); baos.flush(); byte[] buf= baos.toByteArray();//got as bytes here 

Hope this helps!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.