首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将动画图像加载到BufferedImage数组

将动画图像加载到BufferedImage数组
EN

Stack Overflow用户
提问于 2012-01-14 00:11:19
回答 2查看 2.1K关注 0票数 1

我正在尝试将动画纹理无缝地实现到OpenGL游戏中。我创建了一个泛型ImageDecoder类来将任何BufferedImage转换为ByteBuffer。它目前工作得很完美,尽管它不能加载动画图像。

我并不是要将动画图像加载为ImageIcon。我需要BufferedImage来获得一个兼容OpenGL的ByteBuffer。

如何在动画图像中以BufferedImage数组的形式加载每一帧?在类似的注释中,我如何获得动画速率/周期?

Java处理APNG吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-01-14 01:06:48

我不认为Java默认支持APNG,但你可以使用第三方库来解析它:

http://code.google.com/p/javapng/source/browse/trunk/javapng2/src/apng/com/sixlegs/png/AnimatedPngImage.java?r=300

这可能是你最简单的方法。至于从动画gif中获取帧,你必须注册一个ImageObserver:

代码语言:javascript
复制
new ImageIcon( url ).setImageObserver( new ImageObserver() {
    public void imageUpdate( Image img, int infoFlags, int x, int y, int width, int height ) {
        if( infoFlags & ImageObserver.FRAMEBITS == ImageObserver.FRAMEBITS ) {
            // another frame was loaded do something with it.
        }
    }
});

这是在另一个线程上异步加载的,因此不会立即调用imageUpdate()。但它将在解析每个帧时为其调用。

http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/image/ImageObserver.html

票数 0
EN

Stack Overflow用户

发布于 2014-07-17 01:19:39

下面的代码改编自我自己的实现,以适应"into array“部分。

gifs的问题是:如果你想让它与所有的gif一起工作,就必须考虑不同的处理方法。下面的代码试图补偿这一点。例如,"doNotDispose“模式有一个特殊的实现,它将从开始到N的所有帧都绘制到一个BufferedImage中。

与chubbsondubs发布的方法相比,这种方法的优点是它不必等待gif动画延迟,但基本上可以立即完成。

代码语言:javascript
复制
BufferedImage[] array = null;
ImageInputStream imageInputStream = ImageIO.createImageInputStream(new ByteArrayInputStream(data)); // or any other source stream
Iterator<ImageReader> imageReaders = ImageIO.getImageReaders(imageInputStream);
while (imageReaders.hasNext())
{
    ImageReader reader = (ImageReader) imageReaders.next();
    try
    {
        reader.setInput(imageInputStream);
        frames = reader.getNumImages(true);
        array = new BufferedImage[frames];
        for (int frameId : frames)
        {
            int w = reader.getWidth(0);
            int h = reader.getHeight(0);
            int fw = reader.getWidth(frameId);
            int fh = reader.getHeight(frameId);
            if (h != fh || w != fw)
            {
                GifMeta gm = getGifMeta(reader.getImageMetadata(frameId));
                // disposalMethodNames: "none", "doNotDispose","restoreToBackgroundColor","restoreToPrevious",
                if ("doNotDispose".equals(gm.disposalMethod))
                {
                    image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
                    Graphics2D g = (Graphics2D) image.getGraphics();
                    for (int f = 0; f <= frameId; f++)
                    {
                        gm = getGifMeta(reader.getImageMetadata(f));

                        if ("doNotDispose".equals(gm.disposalMethod))
                        {
                            g.drawImage(reader.read(f), null, gm.imageLeftPosition, gm.imageTopPosition);
                        }
                        else
                        {
                            // XXX "Unimplemented disposalMethod (" + getName() + "): " + gm.disposalMethod);
                        }
                    }
                    g.dispose();
                }
                else
                {
                    image = reader.read(frameId);
                    // XXX "Unimplemented disposalMethod (" + getName() + "): " + gm.disposalMethod;
                }
            }
            else
            {
                image = reader.read(frameId);
            }
            if (image == null)
            {
                throw new NullPointerException();
            }
            array[frame] = image;
        }
    }
    finally
    {
        reader.dispose();
    }
}
return array;

private final static class GifMeta
{

    String disposalMethod = "none";
    int imageLeftPosition = 0;
    int imageTopPosition = 0;
    int delayTime = 0;
}

private GifMeta getGifMeta(IIOMetadata meta)
{
    GifMeta gm = new GifMeta();
    final IIOMetadataNode gifMeta = (IIOMetadataNode) meta.getAsTree("javax_imageio_gif_image_1.0");
    NodeList childNodes = gifMeta.getChildNodes();
    for (int i = 0; i < childNodes.getLength(); ++i)
    {
        IIOMetadataNode subnode = (IIOMetadataNode) childNodes.item(i);
        if (subnode.getNodeName().equals("GraphicControlExtension"))
        {
            gm.disposalMethod = subnode.getAttribute("disposalMethod");
            gm.delayTime = Integer.parseInt(subnode.getAttribute("delayTime"));
        }
        else if (subnode.getNodeName().equals("ImageDescriptor"))
        {
            gm.imageLeftPosition = Integer.parseInt(subnode.getAttribute("imageLeftPosition"));
            gm.imageTopPosition = Integer.parseInt(subnode.getAttribute("imageTopPosition"));
        }
    }
    return gm;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8853573

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档