如何使用Java';s ImageIO并保留动画?

如何使用Java';s ImageIO并保留动画?,java,gif,javax.imageio,Java,Gif,Javax.imageio,我正在做一个项目,目标是用ImageIO读取所有图像。这似乎适用于除GIF图像(显示为初始帧的静态图像)以外的所有图像。我在上的一个线程中看到了其他答案,但大多数都需要使用Java的File类,由于程序的SecurityManager,我无法访问该类。我已经能够将GIF分解成一个图像数组并编辑元数据,但在将所有内容重新拼接在一起后,我只能显示一幅图像 以下是该项目的SSCCE: import java.awt.Image; import java.awt.Toolkit; import java

我正在做一个项目,目标是用ImageIO读取所有图像。这似乎适用于除GIF图像(显示为初始帧的静态图像)以外的所有图像。我在上的一个线程中看到了其他答案,但大多数都需要使用Java的File类,由于程序的SecurityManager,我无法访问该类。我已经能够将GIF分解成一个图像数组并编辑元数据,但在将所有内容重新拼接在一起后,我只能显示一幅图像

以下是该项目的SSCCE:

import java.awt.Image;
import java.awt.Toolkit;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class GifRenderer {

  public static void main(String[] args) throws Exception {
    Image image = null;
    byte[] imageByteArray = null;

    try {
      String location = "http://i.imgur.com/Ejh5gJa.gif";
      imageByteArray = createByteArray(location);

      // This works, but I'm trying to use ImageIO
      //image = Toolkit.getDefaultToolkit().createImage(imageByteArray);

      InputStream in = new ByteArrayInputStream(imageByteArray);
      image = ImageIO.read(in);
    } catch (IOException e) {
      e.printStackTrace();
    }

    JFrame frame = new JFrame();
    frame.setSize(300, 300);
    JLabel label = new JLabel(new ImageIcon(image));
    frame.add(label);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }

  // Constraint:  This method simulates how the image is originally received
  private static byte[] createByteArray(String urlString) throws IOException {
    URL url = new URL(urlString);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    InputStream is = null;
    try {
      is = url.openStream ();
      byte[] byteChunk = new byte[4096];
      int n;
      while ( (n = is.read(byteChunk)) > 0 ) {
        baos.write(byteChunk, 0, n);
      }
    } catch (IOException e) {
      e.printStackTrace ();
    } finally {
      if (is != null) { is.close(); }
    }
    return baos.toByteArray();
  }

}
值得一提的一些约束条件可能不清楚:

  • 图像最初作为字节数组接收
  • 图像应由ImageIO读取
  • 最终结果应该是一个图像对象
  • 无法访问文件类

考虑到这些限制,是否还有一种方法可以使用ImageIO来显示GIF,就像
Toolkit.getDefaultToolkit().createImage()
显示图像一样

ImageIO并不真正支持这一点,您可以使用类似的方式加载单个帧,然后由您负责动画。Nb createImageInputStream可以接受InputStream(它甚至可以忽略接受URL,但我需要用文档验证这一点)。ImageIcon和一个JLabel应该做这个技巧如果你真的下定决心(而且有点疯狂),你也可以做一些事情,比如ImageIO对很多事情都很好,显示GIF动画显然不是其中之一。@MadProgrammer在那里做了令人印象深刻的工作,让它真正发挥作用。:-)我感觉ImageIO在这样的限制下不支持正确的GIF渲染(如果有的话)。当前的程序架构可能会使单个帧的动画制作变得非常困难,但至少这是一个选项。谢谢你的回复。