Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java GIF动画未正确重新绘制_Java_Swing_Animation_Gif_Imageicon - Fatal编程技术网

Java GIF动画未正确重新绘制

Java GIF动画未正确重新绘制,java,swing,animation,gif,imageicon,Java,Swing,Animation,Gif,Imageicon,我正在尝试设置GIF图像的动画。动画效果不错,但画得不好 它显示如下(非动画屏幕截图): 在图中,尾巴摆动如下: 正如您所看到的,图像没有很好地重新绘制。我不想使用JLabels,但它不能正常工作,所以我遵循了 我的代码如下: public void draw(JPanel canvas, Graphics2D g2d, int x, int y) { getFrontImage().paintIcon(canvas, g2d, x, y); } ImageIcon gif = new

我正在尝试设置GIF图像的动画。动画效果不错,但画得不好

它显示如下(非动画屏幕截图):

在图中,尾巴摆动如下:

正如您所看到的,图像没有很好地重新绘制。我不想使用JLabels,但它不能正常工作,所以我遵循了

我的代码如下:

public void draw(JPanel canvas, Graphics2D g2d, int x, int y) {
    getFrontImage().paintIcon(canvas, g2d, x, y);
}
ImageIcon gif = new ImageIcon(getClass().getResource(filename));
在其中检索并保存图像,如下所示:

public void draw(JPanel canvas, Graphics2D g2d, int x, int y) {
    getFrontImage().paintIcon(canvas, g2d, x, y);
}
ImageIcon gif = new ImageIcon(getClass().getResource(filename));
在JPanel画布中,我制作了一个绘制方法和一个计时器线程,每10毫秒重新绘制一次。这适用于除GIF之外的所有内容。有人能帮我吗

---编辑


很抱歉误解了,我已经将图像更新为我实际使用的图像。我希望得到正确的答案不会太麻烦…

好的,所以经过大量的研究,我终于能够将框架的处理方法更改为
restoreToBackgroundColor
。基本上,这意味着动画不是一个增量更改,而是一个完整的帧替换

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class AnimatedGifTest1 {

    public static void main(String[] args) {
        new AnimatedGifTest1();
    }

    public AnimatedGifTest1() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new PaintPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class PaintPane extends JPanel {

        private ImageIcon image;

        public PaintPane() {
            image = new ImageIcon(getClass().getResource("/ertcM02.gif"));
            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    repaint();
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return image == null ? new Dimension(200, 200) : new Dimension(image.getIconWidth(), image.getIconHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g); // This is very important!
            int x = (getWidth() - image.getIconWidth()) / 2;
            int y = (getHeight() - image.getIconHeight()) / 2;
            image.paintIcon(this, g, x, y);
        }

    }



}

已更新…

因此,我终于能够查看您正在使用的gif的处理方法,该方法设置为
restoreToPrevious
,根据方法:

恢复到以前的状态。解码器需要将图形覆盖的区域恢复为渲染图形之前的区域

其中,我上面提供的图像使用了
restoreToBackgroundColor
,根据以下方法:

恢复到背景色。图形使用的区域必须恢复为背景色

您可以使用以下代码自己检查它

public static class AnimatedGif {

    public enum DisposalMethod {

        RESTORE_TO_BACKGROUND,
        RESTORE_TO_PREVIOUS,
        DO_NOT_DISPOSE,
        UNSPECIFIED;

        public static DisposalMethod find(String text) {

            DisposalMethod dm = UNSPECIFIED;
            System.out.println(text);

            switch (text) {
                case "restoreToBackgroundColor":
                    dm = RESTORE_TO_BACKGROUND;
                    break;
                case "restoreToPrevious":
                    dm = RESTORE_TO_PREVIOUS;
                    break;
            }

            return dm;

        }
    }

    private List<ImageFrame> frames;
    private int frame;

    public AnimatedGif(JComponent player, URL url) throws IOException {
        frames = new ArrayList<>(25);
        try (InputStream is = url.openStream(); ImageInputStream stream = ImageIO.createImageInputStream(is)) {
            Iterator readers = ImageIO.getImageReaders(stream);
            if (!readers.hasNext()) {
                throw new RuntimeException("no image reader found");
            }
            ImageReader reader = (ImageReader) readers.next();
            reader.setInput(stream);            // don't omit this line!
            int n = reader.getNumImages(true);  // don't use false!
            System.out.println("numImages = " + n);
            for (int i = 0; i < n; i++) {
                BufferedImage image = reader.read(i);
                ImageFrame imageFrame = new ImageFrame(image);

                IIOMetadata imd = reader.getImageMetadata(i);
                Node tree = imd.getAsTree("javax_imageio_gif_image_1.0");
                NodeList children = tree.getChildNodes();

                for (int j = 0; j < children.getLength(); j++) {
                    Node nodeItem = children.item(j);
                    NamedNodeMap attr = nodeItem.getAttributes();
                    switch (nodeItem.getNodeName()) {
                        case "ImageDescriptor":
                            ImageDescriptor id = new ImageDescriptor(
                                            getIntValue(attr.getNamedItem("imageLeftPosition")),
                                            getIntValue(attr.getNamedItem("imageTopPosition")),
                                            getIntValue(attr.getNamedItem("imageWidth")),
                                            getIntValue(attr.getNamedItem("imageHeight")),
                                            getBooleanValue(attr.getNamedItem("interlaceFlag")));
                            imageFrame.setImageDescriptor(id);
                            break;
                        case "GraphicControlExtension":
                            GraphicControlExtension gc = new GraphicControlExtension(
                                            DisposalMethod.find(getNodeValue(attr.getNamedItem("disposalMethod"))),
                                            getBooleanValue(attr.getNamedItem("userInputFlag")),
                                            getBooleanValue(attr.getNamedItem("transparentColorFlag")),
                                            getIntValue(attr.getNamedItem("delayTime")) * 10,
                                            getIntValue(attr.getNamedItem("transparentColorIndex")));
                            imageFrame.setGraphicControlExtension(gc);
                            break;
                    }
                }
                frames.add(imageFrame);
            }
        } finally {
        }
    }

    protected String getNodeValue(Node node) {
        return node == null ? null : node.getNodeValue();
    }

    protected int getIntValue(Node node) {
        return node == null ? 0 : getIntValue(node.getNodeValue());
    }

    protected boolean getBooleanValue(Node node) {
        return node == null ? false : getBooleanValue(node.getNodeValue());
    }

    protected int getIntValue(String value) {
        return value == null ? 0 : Integer.parseInt(value);
    }

    protected boolean getBooleanValue(String value) {
        return value == null ? false : Boolean.parseBoolean(value);
    }

    public class ImageFrame {

        private BufferedImage image;
        private ImageDescriptor imageDescriptor;
        private GraphicControlExtension graphicControlExtension;

        public ImageFrame(BufferedImage image) {
            this.image = image;
        }

        protected void setImageDescriptor(ImageDescriptor imageDescriptor) {
            this.imageDescriptor = imageDescriptor;
        }

        protected void setGraphicControlExtension(GraphicControlExtension graphicControlExtension) {
            this.graphicControlExtension = graphicControlExtension;
            System.out.println(graphicControlExtension.getDisposalMethod());
        }

        public GraphicControlExtension getGraphicControlExtension() {
            return graphicControlExtension;
        }

        public BufferedImage getImage() {
            return image;
        }

        public ImageDescriptor getImageDescriptor() {
            return imageDescriptor;
        }

    }

    public class GraphicControlExtension {

        private DisposalMethod disposalMethod;
        private boolean userInputFlag;
        private boolean transparentColorFlag;
        private int delayTime;
        private int transparentColorIndex;

        public GraphicControlExtension(DisposalMethod disposalMethod, boolean userInputFlag, boolean transparentColorFlag, int delayTime, int transparentColorIndex) {
            this.disposalMethod = disposalMethod;
            this.userInputFlag = userInputFlag;
            this.transparentColorFlag = transparentColorFlag;
            this.delayTime = delayTime;
            this.transparentColorIndex = transparentColorIndex;
        }

        public int getDelayTime() {
            return delayTime;
        }

        public DisposalMethod getDisposalMethod() {
            return disposalMethod;
        }

        public int getTransparentColorIndex() {
            return transparentColorIndex;
        }

        public boolean isTransparentColorFlag() {
            return transparentColorFlag;
        }

        public boolean isUserInputFlag() {
            return userInputFlag;
        }

    }

    public class ImageDescriptor {

        private int imageLeftPosition;
        private int imageTopPosition;
        private int imageHeight;
        private int imageWeight;
        private boolean interlaced;

        public ImageDescriptor(int imageLeftPosition, int imageTopPosition, int imageHeight, int imageWeight, boolean interlaced) {
            this.imageLeftPosition = imageLeftPosition;
            this.imageTopPosition = imageTopPosition;
            this.imageHeight = imageHeight;
            this.imageWeight = imageWeight;
            this.interlaced = interlaced;
        }

        public int getImageHeight() {
            return imageHeight;
        }

        public int getImageLeftPosition() {
            return imageLeftPosition;
        }

        public int getImageTopPosition() {
            return imageTopPosition;
        }

        public int getImageWeight() {
            return imageWeight;
        }

        public boolean isInterlaced() {
            return interlaced;
        }

    }

}
公共静态类{
公共枚举处置方法{
将_还原到_后台,
将_还原为_上一个,
不要处理,
未指明;
公共静态DisposalMethod查找(字符串文本){
处置方法dm=未指定;
System.out.println(文本);
开关(文本){
案例“restoreToBackgroundColor”:
dm=将_恢复到_背景;
打破
“恢复原状”一案:
dm=将_恢复到_之前;
打破
}
返回dm;
}
}
私有列表框架;
私有int帧;
公共AnimatedGif(jComponentPlayer,URL)引发IOException{
帧=新阵列列表(25);
try(InputStream is=url.openStream();ImageInputStream=ImageIO.createImageInputStream(is)){
迭代器读卡器=ImageIO.getImageReaders(流);
如果(!readers.hasNext()){
抛出新的RuntimeException(“未找到图像读取器”);
}
ImageReader=(ImageReader)readers.next();
reader.setInput(stream);//不要忽略这一行!
int n=reader.getNumImages(true);//不要使用false!
System.out.println(“numImages=“+n”);
对于(int i=0;i