动画Gif帧到BufferedImages数组

时间:2015-08-27 20:45:56

标签: java arrays image animated-gif frames

我正在尝试将动画gif的所有帧提取到bufferedimages数组中。我一直在阅读Convert each animated GIF frame to a separate BufferedImage,将每个帧写入单独的文件相当容易。但是当我尝试用帧填充ArrayList而不是编写它时,我的问题出现了。 ArrayList中的每个图像都只是gif的最后一帧。

为了更清楚,这段代码会将每个帧写成完美的单独文件:

    ArrayList<BufferedImage> frames = new ArrayList<BufferedImage>();
    BufferedImage master = new BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB);

    ImageReader ir = new GIFImageReader(new GIFImageReaderSpi());
    ir.setInput(ImageIO.createImageInputStream(gif));
    for (int i = 0; i < ir.getNumImages(true); i++)
    {
        master.getGraphics().drawImage(ir.read(i), 0, 0, null);
        ImageIO.write(master, "gif", new File(dirGifs + "/frames" + i + ".gif"));
    }

但是,这段代码只会给我一个完整相同帧的ArrayList(作为gif的最后一帧)

    ArrayList<BufferedImage> frames = new ArrayList<BufferedImage>();
    BufferedImage master = new BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB);

    ImageReader ir = new GIFImageReader(new GIFImageReaderSpi());
    ir.setInput(ImageIO.createImageInputStream(gif));
    for (int i = 0; i < ir.getNumImages(true); i++)
    {
        master.getGraphics().drawImage(ir.read(i), 0, 0, null);
        frames.add(master);
    }

我认为这是因为我事后没有处理图形,但我尝试创建一个图形对象并处理它并且没有任何改变。需要帮助!

1 个答案:

答案 0 :(得分:0)

Colouredmirrorball指出我可以通过创建bufferedimage的新实例来解决这个问题。所以我先为每个数组元素创建一个新实例,然后将元素的数据设置为与主图像相同。下面的代码为我提供了一个从动画gif文件中提取的帧数组。

public ArrayList<BufferedImage> getFrames(File gif) throws IOException {
    ArrayList<BufferedImage> frames = new ArrayList<BufferedImage>();
    BufferedImage master = new BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB);

    ImageReader ir = new GIFImageReader(new GIFImageReaderSpi());
    ir.setInput(ImageIO.createImageInputStream(gif));
    for (int i = 0; i < ir.getNumImages(true); i++) {
        frames.add(new BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB));
        master.getGraphics().drawImage(ir.read(i), 0, 0, null);
        frames.get(i).setData(master.getData());
    }
    return frames;
}