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]
# 1

What am thinking is there must be a way of opening that file in a text format. There should be (this is an assumption, am no expert in things images) some pattern that marks the end of each frame. If you are able to get that marker, you can split the entire file into the separate images then use Java imaging utilities to save the separate segments as image files.

Regards.

Jamwaa at 2007-7-12 18:03:32 > top of Java-index,Java Essentials,Java Programming...
# 2

> 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());

}

}

Hippolytea at 2007-7-12 18:03:32 > top of Java-index,Java Essentials,Java Programming...
# 3
I can't believe I missed that! Sorry, and thanks for the example.
keeskista at 2007-7-12 18:03:32 > top of Java-index,Java Essentials,Java Programming...
# 4

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.

keeskista at 2007-7-12 18:03:32 > top of Java-index,Java Essentials,Java Programming...
# 5

> 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

Hippolytea at 2007-7-12 18:03:32 > top of Java-index,Java Essentials,Java Programming...