How to draw GIF with ImageIO and drawImage

1

I need to draw a GIF, I have the following code:

public BasicBlock(String path, String name, int id, boolean gif){
    this.path = path;
    this.name = name;
    this.id = id;   

    File img = new File(path);
    try {
        image = ImageIO.read(img);
    } catch (IOException e) {}
}

public static BufferedImage getBlockById(int id){
    return blocks[id].getImage();
}

g.drawImage(Blocks.getBlockById(id), x, y, null);
    
asked by anonymous 10.07.2017 / 02:22

1 answer

2

Although% wc is used to load images, and a gif is also an image, the problem of using this class for gifs is that it will load only the first frame.

To properly load the gif, you need to create a ImageIO , retrieve a type ImageIcon and pass to method Image " in% panel% or other component where you will draw the gif.

In addition, you also need to set an image viewer for drawImage() , it is he who will take care of the animation.

I've set an example so you can see in practice:

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

import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class DrawGiFTest extends JComponent {

    public void createAndShowGUI() {

        JFrame window = new JFrame();

        window.getContentPane().add(new GifPanel(loadImage("http://introcs.cs.princeton.edu/java/15inout/duke.gif")));
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setPreferredSize(new Dimension(300, 300));

        window.pack();
        window.setVisible(true);
    }

    //Este método recebe uma string com a url da imagem e
    //cria um ImageIcon e retorna um tipo Image, com o 
    //gif já carregador corretamente
    private Image loadImage(String url){

        ImageIcon icon;

        try {
            icon = new ImageIcon(new URL(url)); 
            Image img = icon.getImage();
            return img;
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return null;
        }
    }

    class GifPanel extends JComponent{

        Image image;

        public GifPanel(Image image) {
            this.image = image;
        }

        @Override
        protected void paintComponent(Graphics g) {

            super.paintComponent(g);
            g.drawImage(image, 50, 50, this);
        }

    }


    public static void main(String[] a) {

        SwingUtilities.invokeLater(() -> {
            new DrawGiFTest().createAndShowGUI();
        });
    }
}

The result:

Inthiscase,IspentpaintComponent(),because drawImage implements a this . If it is to draw on any other component (such as JComponent , JButton, etc ...), you can pass ImageObserver also, since all swing components (except the top-level containers ) inherit from JPanel directly or indirectly.

References:

10.07.2017 / 03:51