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

Java:在其他动画gif上叠加/覆盖动画gif,java,swing,overlay,gif,animated,Java,Swing,Overlay,Gif,Animated,我在做一个小游戏。这不是一个动作游戏,而是一个谜题游戏,所以表演并没有那么重要。 现在,我有了主要的游戏区域,一个背景图像。在某些情况下,我希望在背景图像的部分上绘制其他图像。 我的问题是背景图像和叠加图像都可以是动画GIF,帧数未知(基本上是用户选择的) 现在,我想做的基本上是:绘制背景图像并设置动画(如果是gif),然后在其上绘制0-n个较小的动画gif,相对于背景图像的位置,以像素坐标表示。 此外,它应该可以调整大小,以便图像相应地缩放/移动 最终结果会是什么样子:(想象一下它是动画) 我

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

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

最终结果会是什么样子:(想象一下它是动画)

我找到了一个解决方案,将布局管理器设置为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是有问题的(特别是因为我想稍后向图像添加一些文本,尽管我会在背景中使用另一个标签,而不是背景标签本身或其他东西),而且这种方式似乎不可能调整大小,因为我无法调整JLabels图像图标的大小(找到了一些解决方案,将gif拆分为每层一个BuffereImage,并在重新组合之前调整它们的大小,从而在帧之间丢失特定的延迟等)。此外,由于位置应该是像素完美的,因此,由于舍入错误,即使可能也会出现调整大小的问题

现在,有更好的方法吗? 我是否可以加载动画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);
    }
}

这对我有用。较小的轨道图像位于较大的月球相位图像的中心

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);
    }
}

如果前景图像应该居中,则此(或其他布局管理器)也可以,但它必须位于非常特定的位置。例如,想象一下,背景图像显示一个带有空画框的墙,其中,在鼠标上方,应显示(覆盖)动画gif。它必须正好在框架内,因此我能想到的所有布局管理器都无法工作。什么,那么“空画框”(不管是什么)没有居中?它是移动的,还是处于静态位置?+1 for;克劳伊:可能值得一看提示:添加@trashgood(或者其他什么人,
@
很重要)通知此人新的评论。我认为这可能是“忘记布局管理器,将所有图像绘制到一个
JLabel
中显示的
buffereImage
”。不过我喜欢垃圾神的建议。@Klaue:使用
setSize()
使您负责正确的大小;请注意这一点。在您的系统中,请通过
URL
访问发布的图像,如图所示;使用合成图像,如图所示;或使用
UIManager
图标,如图所示。