Java ImageWriter BufferedImage to GIF

眉间皱痕 提交于 2021-02-08 05:23:46

问题


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:


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();



回答2:


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!



来源:https://stackoverflow.com/questions/14488452/java-imagewriter-bufferedimage-to-gif

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!