Seperate animated GIF frames
I'm sure this has been discusses mant times before, but the search of this forum seems to ignore all posts older then a year.
Basically I want to load a animated GIF and save all frames as seperate images. The saving is not a problem, but how on earth do I get access to the different frames? The standard ImageIO is able to load animated GIFs, but as far as I know there is no way to get to the sub-images.
A really poor solution would be to make a thread that repaints a panel every X time, and then save the graphics of the panel when it's different from the previous step. But I'm sure there is a less silly way than this...
[650 byte] By [
keeskista] at [2007-11-27 6:36:07]

> What am thinking is there must be a way of opening that file in a text format.
<cringe/> A GIF file is not a text file.
OP: You didn't look very hard at package javax.imageio. ImageReader has methods getNumImages and read(imageIndex):
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.imageio.*;
import javax.swing.*;
import java.util.List;
public class ImageListExample implements Runnable {
public void run() {
List < BufferedImage > images = getImages();
JPanel p = new JPanel(new GridLayout(0,4));
for(BufferedImage image : images) {
JLabel label = new JLabel(new ImageIcon(image));
label.setBorder(BorderFactory.createEtchedBorder());
p.add(label);
}
JFrame f = new JFrame("ImageListExample");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(p);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
List < BufferedImage > getImages() {
List < BufferedImage > images = new ArrayList < BufferedImage > ();
try {
URL url = new URL("http://www.cs.princeton.edu/introcs/15inout/duke.gif");
ImageReader reader = ImageIO.getImageReadersBySuffix("gif").next();
reader.setInput(ImageIO.createImageInputStream(url.openStream()));
int ub = reader.getNumImages(true);
for(int i = 0; i < ub; ++i)
images.add(reader.read(i));
} catch (IOException e) {
throw new RuntimeException(e);
}
return images;
}
public static void main(String[] args) {
EventQueue.invokeLater(new ImageListExample());
}
}
It seems that frames after the first one only contain the section of the image that has actually been updated, much like most video formats. However, the method that I se for getting the offset of each frame, ImageReader.getTileGridXOffset(int) and ImageReader.getTileGridYOffset(int) always seem to return 0, making it impossible to re-create the animation.
> It seems that frames after the first one only contain
> the section of the image that has actually been
> updated, much like most video formats. However, the
> method that I se for getting the offset of each
> frame, ImageReader.getTileGridXOffset(int) and
> ImageReader.getTileGridYOffset(int) always seem to
> return 0, making it impossible to re-create the
> animation.
BufferedImages are all one single tile, so those methods won't help.
You'll have to dig around in the XML metadata to find the (x,y) offsets
for each frame. I did it once, let me see if I can retrieve the example...
Here it is: http://forum.java.sun.com/thread.jspa?forumID=20&threadID=500348
The URL is uses no longer exists, put edit it and give it a whirl...
Message was edited by:
Hippolyte