动态GIF中帧之间的读取延迟

3

如何在每帧之间读取动画GIF的控制块?我对每帧之间的延迟感兴趣。我查看了ImageReader的Javadoc,但没有找到任何信息。

这是我的代码,用于从动画GIF中读取所有帧,我该如何增强它以读取嵌入在动画GIF中的每个帧的元数据?

    List<BufferedImage> list = new ArrayList<BufferedImage>();
    try {
        ImageReader reader = ImageIO.getImageReadersBySuffix("gif").next();
        reader.setInput(ImageIO.createImageInputStream(urlImage.openStream()));
        int i = reader.getMinIndex();
        int numImages = reader.getNumImages(true);
        while (i < numImages)
        {
            list.add(reader.read(i++));
        }

        // do stuff with frames of image...

    } catch (Exception e) {
        e.printStackTrace();
    }
1个回答

5
您需要从元数据节点中查找“delayTime”属性。使用以下有效示例来理解:
public class GiffTest {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {
        ImageReader reader = ImageIO.getImageReadersBySuffix("gif").next();
        reader.setInput(ImageIO.createImageInputStream(new FileInputStream("H:\\toonGif.gif")));
        int i = reader.getMinIndex();
        int numImages = reader.getNumImages(true);

        IIOMetadata imageMetaData =  reader.getImageMetadata(0);
        String metaFormatName = imageMetaData.getNativeMetadataFormatName();

    IIOMetadataNode root = (IIOMetadataNode)imageMetaData.getAsTree(metaFormatName);

    IIOMetadataNode graphicsControlExtensionNode = getNode(root, "GraphicControlExtension");

        System.out.println(graphicsControlExtensionNode.getAttribute("delayTime"));
    }

    private static IIOMetadataNode getNode(IIOMetadataNode rootNode, String nodeName) {
        int nNodes = rootNode.getLength();
        for (int i = 0; i < nNodes; i++) {
            if (rootNode.item(i).getNodeName().compareToIgnoreCase(nodeName)== 0) {
            return((IIOMetadataNode) rootNode.item(i));
            }
       }
        IIOMetadataNode node = new IIOMetadataNode(nodeName);
        rootNode.appendChild(node);
        return(node);
  }
}

2
看起来实际上是以百分之一秒为单位。根据动画GIF维基百科的解释,许多渲染程序将瓦片或图层解释为动画帧,并按顺序无限循环地显示它们作为动画[11],大多数网络浏览器会自动以0.1秒的延迟时间显示这些帧。 - medloh
1
维基百科对此非常清楚:“每帧动画延迟以百分之一秒为单位在GCE中指定。” http://en.wikipedia.org/wiki/Graphics_Interchange_Format - medloh
@medloh,请忽略我之前的评论。我很难联系到你。是的,维基百科上的内容是正确的,正如你所读到的一样。查看此链接,了解延迟时间的实际工作方式。 - Sage
1
我从哪里可以找到 "ImageIO、IIOMetadata、IIOMetadataNode" 类? - Naitik
1
@Naitik,请查看文档页面。它们是javax.imageio包的一部分,例如:ImageIO - Sage
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接