Java ImageWriter BufferedImage to GIF



我希望你们能帮我解决这个问题。我不确定这是 Java 中的错误还是我做错了什么,但我会选择后者。

我想将缓冲图像转换为GIF图像。然后,我希望将 GIF 以字节数组的形式保存在内存中。(我不想将文件保存到磁盘)

程序应该捕获一个屏幕片段(只是为了创建一个快速图像),并使用ImageIO ImageWriter和ByteArrayOutputStream将其转换为GIF字节数组。

下面的代码将向您展示该错误。程序将崩溃并给出一个 ArrayIndexOutOfBoundsException,并且数组保持为空。如果您将"gif"替换为"png",它将正常工作,因此我感到困惑。也!如果我将图像保存到磁盘上的文件

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

它会将其正确保存到.gif文件中。

所以我的问题是,我在这一段代码中做错了什么?任何帮助将不胜感激!:)

注意:这不是动画GIF,也不涉及透明度。

    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]);
    }
似乎在

com.sun.imageio.plugins.gif.*中有一些奇怪的(如果不是明显的错误)流缓冲实现。如果不显式刷新或关闭 ImageOutputStream,则即使在关闭基础流后,也不会刷新内容。改变

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

   ImageOutputStream imageos = ImageIO.createImageOutputStream(out);
   write.setOutput(imageos);
   write.write(gif);
   imageos.close();  // or imageos.flush();
您必须

使用ByteArrayOutputStream来获取字节形式的图像。要写入此ByteArrayOutputStream,您应该用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

希望这有帮助!

最新更新