【问题标题】:Animated Gif Frames To Array of BufferedImages动画 Gif 帧到 BufferedImages 数组
【发布时间】:2015-11-22 09:52:05
【问题描述】:

我正在尝试将动画 gif 的所有帧提取到缓冲图像数组中。我一直在阅读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);
    }

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

【问题讨论】:

    标签: java arrays image animated-gif frames


    【解决方案1】:

    这是因为BufferedImage master 作为引用而不是副本存储在 ArrayList 中。所以 ArrayList 的每个元素都指向同一个 BufferedImage。我认为解决这个问题的最简单方法就是将行 BufferedImage master = new BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB); 放在 for 循环中,这样每次迭代都会创建一个新的 BufferedImage 实例。

    【讨论】:

    • 每次迭代我都需要在主图像上绘制,因此新实例将无法工作。所以我所做的是为数组的每个元素创建一个新实例,然后设置其数据以匹配主图像。谢谢,您的回答帮助我很快找到了解决方案
    【解决方案2】:

    Colouredmirrorball 指出我可以通过创建缓冲图像的新实例来解决这个问题。所以我首先为每个数组元素创建了一个新实例,然后将元素的数据设置为与主图像相同。以下代码为我提供了从动画 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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-08
      • 1970-01-01
      • 2021-07-21
      相关资源
      最近更新 更多