Java:在其他动画gif上叠加/叠加动画gif

时间:2013-08-25 20:14:37

标签: java swing overlay gif animated

我正在制作一款小游戏。这不是一个动作,而是一个谜题,所以表现并不那么重要。 现在,我有主要的游戏区域,一个背景图片。在某些情况下,我想在背景图像的一部分上绘制其他图像。 我的问题是背景图像和叠加的图像都可以是GIF动画,帧数未知(基本上是用户选择的)。

现在,我想要做的基本上是:绘制背景图像并将其设置为动画(如果它是gif),然后在其上绘制0-n个较小的GIF动画,相对于背景图像的位置,以像素给出坐标。 此外,它应该可以调整大小,以便图像相应地缩放/移动。

最终结果如何:http://i.stack.imgur.com/PxdDt.png(想象一下它是动画的)

我找到了一个解决方案,通过将布局管理器设置为null并使用带有图标的绝对定位的JLabel将它们设置为动画,使用一个作为背景,另一个作为前景添加到它:

background.setSize(backgroundIcon.getIconWidth(), backgroundIcon.getIconHeight());
foreground.setSize(foregroundIcon.getIconWidth(), foregroundIcon.getIconHeight());
background.setLocation(0, 0);
foreground.setLocation(30, 30);
background.setLayout(null);
background.add(foreground);
frame.setLayout(null);
frame.add(background);

(下面的完整代码)

正如我所说,将布局管理器设置为null是有问题的(特别是因为我以后想要在图像中添加一些文本,尽管我在背景中使用了另一个Label,而不是背景标签因为我无法调整JLabels图像图标的大小(找到一些将gif分成每层一个bufferedImage并将它们全部重新调整大小然后再将它们重新组合在一起的解决方案,因此调整大小似乎不可能这样。它丢失帧之间的特定延迟等等)。此外,由于位置应该是像素完美的,因此尽管可能,但由于舍入误差可能会出现问题。

现在,有更好的方法吗? 我可以以某种方式加载动画GIF并手动合并(即使很难,他们可能有不同的层数)所以我只需要绘制一个图像?是否有布局管理器,我可以手动设置组件位置,但如果您调整窗口/面板的大小,它会自动缩放它?可能有第三方图形项目可以做我想要的蝙蝠吗?

理想情况下,如果它们不是动画,我会做的事情,比如构建合并的图像,然后调整大小并显示它。

完整代码:

import java.awt.Dimension;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public final class Tester  extends JFrame {
    public static void main(String[] args) throws MalformedURLException {
        new Tester();
    }

    private Tester() throws MalformedURLException {
        setTitle("Tester");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Icon backgroundIcon = new ImageIcon(new URL("http://s5.favim.com/orig/51/animated-gif-gif-hands-sign-language-Favim.com-542945.gif"));
        Icon foregroundIcon = new ImageIcon(new URL("http://i.imgur.com/89HANHg.gif"));

        JLabel background = new JLabel(backgroundIcon);
        JLabel foreground = new JLabel(foregroundIcon);

        // ugly
        background.setSize(backgroundIcon.getIconWidth(), backgroundIcon.getIconHeight());
        foreground.setSize(foregroundIcon.getIconWidth(), foregroundIcon.getIconHeight());
        background.setLocation(0, 0);
        foreground.setLocation(30, 30);
        background.setLayout(null);
        background.add(foreground);
        setLayout(null);
        add(background);

        // set size of frame to size of content
        setResizable(false);
        getContentPane().setPreferredSize(new Dimension(backgroundIcon.getIconWidth(), backgroundIcon.getIconHeight()));
        pack();

        setLocationRelativeTo(null);
        setVisible(true);
    }
}

1 个答案:

答案 0 :(得分:3)

这对我有用。较小的轨道图像位于较大的月相图像内部。

import java.awt.*;
import javax.swing.*;
import java.net.*;

public final class Tester  extends JFrame {
    public static void main(String[] args) throws MalformedURLException {
        new Tester();
    }

    private Tester() throws MalformedURLException {
        setTitle("Tester");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Icon backgroundIcon = new ImageIcon(
                new URL("http://1point1c.org/gif/moon/moonphases.gif"));
        Icon foregroundIcon = new ImageIcon(
                new URL("http://1point1c.org/gif/thum/plnttm.gif"));

        JLabel background = new JLabel(backgroundIcon);
        JLabel foreground = new JLabel(foregroundIcon);

        background.setLayout(new GridBagLayout());
        background.add(foreground);
        add(background);

        pack();

        setLocationByPlatform(true);
        setVisible(true);
    }
}