How to get length (in time) from an animated GIF

2019-04-29 16:23发布

Is there a way to find out how long a single-loop animated GIF will take to finish?

2条回答
Bombasti
2楼-- · 2019-04-29 16:25

Well, the specifics sorta depends on what interface you're using to manipulate those animated GIFs (I'm not aware of a real slick way in native Java/AWT/Swing), however the basic idea would to calculate (frame rate * number of frames).

If you're coding a GIF manipulation tool by hand, I recommend taking a look at http://www.onicos.com/staff/iz/formats/gif.html

Hope this helps at least a little.

Update: Try implement the ImageObserver interface. Take a look at the ImageObserver.FRAMEBITS flag in that class to detect frame updates. http://docs.oracle.com/javase/6/docs/api/java/awt/image/ImageObserver.html

This still leaves the question of how many frames the gif has. You might want to try taking a look at the Image.getProperty() function. I'm having some difficulty finding documentation as to whether there's a "frame" property, but take a look.

查看更多
Lonely孤独者°
3楼-- · 2019-04-29 16:51

Use library Metadata-Extractor to read Meta info of the Image files. The below code snippet can be used to read GifControlDirectory for each Image(frame) in the GIF file.

/**
 * Get time length of GIF file in milliseconds.
 *
 * @return time length of gif in ms.
 */
public int getGifAnimatedTimeLength(String imagePath) {
    Metadata metadata = ImageMetadataReader.readMetadata(imagePath);
    List<GifControlDirectory> gifControlDirectories =
            (List<GifControlDirectory>) metadata.getDirectoriesOfType(GifControlDirectory.class);

    int timeLength = 0;
    if (gifControlDirectories.size() == 1) { // Do not read delay of static GIF files with single frame.
    } else if (gifControlDirectories.size() >= 1) {
        for (GifControlDirectory gifControlDirectory : gifControlDirectories) {
            try {
                if (gifControlDirectory.hasTagName(GifControlDirectory.TAG_DELAY)) {
                    timeLength += gifControlDirectory.getInt(GifControlDirectory.TAG_DELAY);
                }
            } catch (MetadataException e) {
                e.printStackTrace();
            }
        }
        // Unit of time is 10 milliseconds in GIF.
        timeLength *= 10;
    }
    return timeLength;
}

Note that even if GIF file has multiple frames, it is quite possible that each frame may have delay of 0 or no TAG_DELAY metadata. Also, this article details another issue of how various platforms use delay value.

查看更多
登录 后发表回答