如何在 JavaFX 中停止动画 GIF? [英] How I can stop an animated GIF in JavaFX?

查看:45
本文介绍了如何在 JavaFX 中停止动画 GIF?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的项目中使用动画 GIF,但我不知道如何停止循环动画.我的意思是,我希望 GIF 只播放 1 次.

I want to use an animated GIF in my project, but I dont know how I can stop the loop animation. I mean, I want the GIF to play 1 time only.

谢谢!

推荐答案

我没有做过 GIF 动画,甚至不知道 JavaFX 会有启动和停止它们的方法.如果您想使用图像制作任何动画,我建议您自己逐帧制作.这样您就可以完全控制它,并且您的图像中可以有超过 256 种颜色.

I haven't done GIF animation, wasn't even aware that JavaFX would have methods for starting and stopping them. If you wish to do ANY animation using images, I rather suggest you do it frame by frame yourself. This way you have full control over it and you can have more than just 256 colors in your image.

我读了一篇关于创建精灵动画的非常好的文章JavaFX 在 Mike 的博客中.

I read a very good article about Creating a Sprite Animation with JavaFX in Mike's blog.

这很容易做到.您只需扩展 Transition 类,添加一个 ImageView 并实现 Transition 的 插值方法.

It's very easy to do. You simply extend the Transition class, add an ImageView to it and implement the Transition's Interpolate method.

哦,顺便说一下,GIF 有一个循环标志,告诉它们要么循环播放,要么不循环播放.换句话说:理论上你可以修改 GIF 文件的循环属性.仅在理论上,因为我只是尝试指定只播放一次,而在 JavaFX 中它仍然在无限循环中播放,而在 FireFox 中它播放了一次.顺便说一下,JavaFX 似乎不支持支持超过 256 种颜色的动画 PNG (APNG).所以自动图像动画功能非常有限.最好自己做动画.

oh, and by the way, GIFs have a loop flag which tells them to either play in a loop or not to play in a loop. In other words: In theory you could modify the GIF file's loop property. In theory only, because I just tried with specifying to play only once and in JavaFX it still played in an endless loop while in FireFox it played once. By the way, JavaFX doesn't seem to support animated PNGs (APNG) which would support more than 256 colors. So the automatic image animation capabilities are very limited. Best to do the animation by yourself.

我希望有人想出更好的东西,但这里有一个示例代码,说明如何完全控制您的 gif.

I hope someone comes up with something better, but here's an example code about how you could get full control over your gif.

import java.awt.image.BufferedImage;
import java.net.URISyntaxException;

import javafx.animation.Interpolator;
import javafx.animation.Transition;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Duration;

/**
 * Requires GifDecoder from here: http://www.java2s.com/Code/Java/2D-Graphics-GUI/DecodesaGIFfileintooneormoreframes.htm
 */
public class AnimatedGifDemo extends Application {

    @Override
    public void start(Stage primaryStage) throws URISyntaxException {

        HBox root = new HBox();

        // TODO: provide gif file, ie exchange banana.gif with your file
        Animation ani = new AnimatedGif(getClass().getResource("banana.gif").toExternalForm(), 1000);
        ani.setCycleCount(10);
        ani.play();

        Button btPause = new Button( "Pause");
        btPause.setOnAction( e -> ani.pause());

        Button btResume = new Button( "Resume");
        btResume.setOnAction( e -> ani.play());

        root.getChildren().addAll( ani.getView(), btPause, btResume);

        Scene scene = new Scene(root, 1600, 900);

        primaryStage.setScene(scene);
        primaryStage.show();

    }

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

    public class AnimatedGif extends Animation {

        public AnimatedGif( String filename, double durationMs) {

            GifDecoder d = new GifDecoder();
            d.read( filename);

            Image[] sequence = new Image[ d.getFrameCount()];
            for( int i=0; i < d.getFrameCount(); i++) {

                WritableImage wimg = null;
                BufferedImage bimg = d.getFrame(i);
                sequence[i] = SwingFXUtils.toFXImage( bimg, wimg);

            }

            super.init( sequence, durationMs);
        }

    }

    public class Animation extends Transition {

        private ImageView imageView;
        private int count;

        private int lastIndex;

        private Image[] sequence;

        private Animation() {
        }

        public Animation( Image[] sequence, double durationMs) {
            init( sequence, durationMs);
        }

        private void init( Image[] sequence, double durationMs) {
            this.imageView = new ImageView(sequence[0]);
            this.sequence = sequence;
            this.count = sequence.length;

            setCycleCount(1);
            setCycleDuration(Duration.millis(durationMs));
            setInterpolator(Interpolator.LINEAR);

        }

        protected void interpolate(double k) {

            final int index = Math.min((int) Math.floor(k * count), count - 1);
            if (index != lastIndex) {
                imageView.setImage(sequence[index]);
                lastIndex = index;
            }

        }

        public ImageView getView() {
            return imageView;
        }

    }

}

它提供了一个暂停/恢复按钮用于测试.您还需要的是 Gif 解码器代码和动画 banana.gif.

It provides a pause/resume button for testing. What you need in addition is the Gif Decoder code and an animated banana.gif.

这篇关于如何在 JavaFX 中停止动画 GIF?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆