Alex Rivera | Logout

Convert each animated GIF frame to a separate BufferedImage

Asked 2012-01-19T21:52:48.110
22

I want to be able to take an animated GIF as input, count the frames (and perhaps other metadata), and convert each to a BufferedImage. How can I do this?

Edit
Report

1 Answer

13

None of the answers here are correct and suitable for animation. There are many problems in each solution so I wrote something that actually works with all gif files. For instance, this takes into account the actual width and height of the image instead of taking the width and height of the first frame assuming it will fill the entire canvas, no, unfortunately it's not that simple. Second, this doesn't leave any transparent pickles. Third, this takes into account disposal Methods. Fourth, this gives you delays between frames (* 10 if you want to use it in Thread.sleep()).

private ImageFrame[] readGif(InputStream stream) throws IOException{
    ArrayList<ImageFrame> frames = new ArrayList<ImageFrame>(2);

    ImageReader reader = (ImageReader) ImageIO.getImageReadersByFormatName("gif").next();
    reader.setInput(ImageIO.createImageInputStream(stream));

    int lastx = 0;
    int lasty = 0;

    int width = -1;
    int height = -1;

    IIOMetadata metadata = reader.getStreamMetadata();

    Color backgroundColor = null;

    if(metadata != null) {
        IIOMetadataNode globalRoot = (IIOMetadataNode) metadata.getAsTree(metadata.getNativeMetadataFormatName());

        NodeList globalColorTable = globalRoot.getElementsByTagName("GlobalColorTable");
        NodeList globalScreeDescriptor = globalRoot.getElementsByTagName("LogicalScreenDescriptor");

        if (globalScreeDescriptor != null && globalScreeDescriptor.getLength() > 0){
            IIOMetadataNode screenDescriptor = (IIOMetadataNode) globalScreeDescriptor.item(0);

            if (screenDescriptor != null){
                width = Integer.parseInt(screenDescriptor.getAttribute("logicalScreenWidth"));
                height = Integer.parseInt(screenDescriptor.getAttribute("logicalScreenHeight"));
            }
        }

        if (globalColorTable != null && globalColorTable.getLength() > 0){
            IIOMetadataNode colorTable = (IIOMetadataNode)
answered 2013-06-24T06:54:12.617

Your Answer