【问题标题】:How to extend BufferedImage in order to create an "animated image" that consists of multiple BufferedImages如何扩展 BufferedImage 以创建包含多个 BufferedImage 的“动画图像”
【发布时间】:2013-11-28 22:45:58
【问题描述】:

我需要创建一个类 AnimatedImage,它将获取一个 Image 对象数组并在给定的时间间隔内以循环方式显示它们。

这个想法是让 Swing 组件使用这个 AnimatedImage 类,就像它们使用常规 BufferedImage 来显示图像一样。 AnimatedImage会循环切换实际图片,并通知swing组件显示下一张实际图片。

我的问题是我找不到通知摆动组件 AnimatedImage 已切换实际图像的方法。

希望你能明白我的意思。

任何帮助将不胜感激!

到目前为止我做了什么:

public class AnimatedImage extends BufferedImage
{
    private final Image[] images;

    private int imageIndex = 0;

    public AnimatedImage(Image[] images, int interval)
    {
        super(images[0].getWidth(null), images[0].getHeight(null), BufferedImage.TYPE_INT_ARGB);

        this.images = images;

        ActionListener listener = new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                iterate();
            }
        };
        Timer timer = new Timer(interval, listener);
        timer.start();
    }

    private void iterate()
    {
        imageIndex = imageIndex + 1 >= images.length ? 0 : imageIndex + 1;
    }

    public float getAccelerationPriority()
    {
        return images[imageIndex].getAccelerationPriority();
    }
    public ImageCapabilities getCapabilities(GraphicsConfiguration gc)
    {
        return images[imageIndex].getCapabilities(gc);
    }
    public Image getScaledInstance(int width, int height, int hints)
    {
        return images[imageIndex].getScaledInstance(width, height, hints);
    }
    @Override
    public Graphics getGraphics()
    {
        return images[imageIndex].getGraphics();
    }

    @Override
    public int getHeight(ImageObserver observer)
    {
        return images[imageIndex].getHeight(observer);
    }

    @Override
    public Object getProperty(String name, ImageObserver observer)
    {
        return images[imageIndex].getProperty(name, observer);
    }

    @Override
    public ImageProducer getSource()
    {
        return images[imageIndex].getSource();
    }

    @Override
    public int getWidth(ImageObserver observer)
    {
        return images[imageIndex].getWidth(observer);
    }
}

【问题讨论】:

  • “如何扩展 BufferedImage 以创建由多个 BufferedImage 组成的“动画图像” JSE 对动画 GIF 的支持建议 BufferedImage (& @987654324 @ 就此而言)已经支持动画图像。有关创建动画的提示,请参阅 this answer
  • 是的,我知道 JSE 支持动画 GIF。问题是我不想使用实际的动画,而是通过循环切换不同的图像来模拟它。
  • “问题是我不想使用实际的动画......”(耸耸肩)好吧 - 我正在准备一个例子,但我不会打扰。 .
  • @AndrewThompson:如果你是对的,那么我的回答就是错误的。请看我的回答,让我知道。谢谢。
  • @AndrewThompson:如果我错了,那么你真的应该提供一个应该被接受的答案,如果不是为了 OP,那么对于这个网站的未来访问者确实需要动画.再次感谢!

标签: java image swing


【解决方案1】:

在我看来,您做错了,扩展 BufferedImage 不会给您任何工具来通知或显示更改。为了我的钱,我会创建几个 ImageIcon 并使用 Swing Timer 交换 JLabel 中的图标。


编辑
您在评论中声明:

为什么不呢?我确信有一种方法可以通知或显示更改。无论是通过实现/传递 ImageObserver 还是其他方式......我有一个非常大的 JComponents 基础设施,这些基础设施严重依赖于 Image 实例。我不能简单地开始使用图标和 JLabels

因为:

  1. 在我看来,你的类并不代表与 BufferedImage 真正的“is-a”关系,BufferedImage 是一个具体的图像,为它的颜色保存一个数据缓冲区。您尝试的解决方案违反了 Liskov 替换原则,因为无论您如何构建解决方案,您的新类都不可能在其他情况下替代 BufferedImage 并使其正常工作。
  2. 您尝试的解决方案深入研究了对 Image 子类的低级概念进行根本性更改,而维护使用高级概念的解决方案几乎总是更安全、更容易。
  3. 你的问题闻起来很像XY-problem。有时,实际上更好地重构你的代码。

【讨论】:

  • 为什么不呢?我确信有一种方法可以通知或显示更改。无论是通过实现/传递 ImageObserver 还是其他方式......我有一个非常大的 JComponents 基础设施,这些基础设施严重依赖于 Image 实例。我不能简单地开始使用图标和 JLabels...
  • +1, @mdzh,For my money, I'd instead create several ImageIcons and swap the Icons in a JLabel using a Swing Timer. - 例如见Animated Icons
  • @camickr,我设法使用这篇文章做我想做的事。我使用图像和 Graphics2D 对象而不是图标来绘制它们。我还需要将合成设置为 AlphaComposite.SRC,这样新图像就不会叠加。非常感谢!!
猜你喜欢
  • 2012-03-12
  • 2012-01-03
  • 1970-01-01
  • 1970-01-01
  • 2013-07-24
  • 1970-01-01
  • 1970-01-01
  • 2013-07-01
  • 2015-09-07
相关资源
最近更新 更多