Comment puis-je arrêter un GIF animé dans JavaFX?


Je veux utiliser un GIF animé dans mon projet, mais je ne sais pas comment je peux arrêter l'animation en boucle. Je veux dire, je veux que le GIF joue 1 fois seulement.

Merci!

Author: Ezequiel, 2015-01-28

1 answers

Je n'ai pas fait d'animation GIF, je ne savais même pas que JavaFX aurait des méthodes pour les démarrer et les arrêter. Si vous souhaitez faire UNE animation en utilisant des images, je vous suggère plutôt de le faire image par image vous-même. De cette façon, vous avez un contrôle total sur elle et vous pouvez avoir plus que seulement 256 couleurs dans votre image.

J'ai lu un très bon article sur La création d'une animation Sprite avec JavaFX dans le blog de Mike.

, Il est très facile à faire. Vous étendez simplement la transition classe, ajoutez-y un ImageView et implémentez la méthode d'interpolation de la transition .

Edit: oh, et en passant, les GIF ont un drapeau de boucle qui leur dit de jouer en boucle ou de ne pas jouer en boucle. En d'autres termes: En théorie, vous pouvez modifier la propriété loop du fichier GIF. En théorie seulement, parce que j'ai juste essayé de spécifier de ne jouer qu'une seule fois et dans JavaFX, il jouait toujours dans une boucle sans fin alors que dans FireFox, il jouait une fois. Au fait, JavaFX ne semble pas supporter PNGS animés (APNG) qui supporterait plus de 256 couleurs. Les capacités d'animation d'image automatique sont donc très limitées. Mieux vaut faire l'animation par vous-même.

J'espère que quelqu'un propose quelque chose de mieux, mais voici un exemple de code sur la façon dont vous pourriez avoir un contrôle total sur votre 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;
        }

    }

}

Il fournit un bouton pause/reprise pour les tests. Ce dont vous avez besoin en plus, c'est du Code de décodeur Gif et d'une banane animée .gif .

entrez la description de l'image ici

 9
Author: Roland, 2015-01-28 17:30:52