使用libgd在C中逐帧处理Gif

时间:2018-10-24 08:25:27

标签: c gif

我有一个用来处理各种图像文件的程序。当前,它仅适用于静态图像。我想提供对gif的支持,并且我一直在寻找乏味的doc u ment a tion,但找不到任何有关如何逐帧操作gif的参考。

理想情况下,我想一次遍历gif,使用其他功能操纵文件中的每个帧,然后重新包装图像。

1 个答案:

答案 0 :(得分:1)

如果您仔细观察the source code,则在使用动画帧时可以轻松找到一个较弱的实现。

  

代码并不说谎:调用gdImageCreateFromGif(FILE *fdFile)gdImageCreateFromGifPtr (int size, void *data)时,它直接调用gdImageCreateFromGifCtx(gdIOCtxPtr fd),因此您必须 read'n'search 那个功能乱七八糟。该文档没有相关信息,因为该库非常非常老。

在源代码(6月22日为 fd06f7f )行258(gdImageCreateFromGifCtx(gdIOCtxPtr fd)):

for (;;) {
    int top, left;
    int width, height;

    if(!ReadOK(fd, &c, 1)) {
        return 0;
    }

    if (c == ';') { /* GIF terminator */
        goto terminated;
    }

    if(c == '!') { /* Extension */
        if(!ReadOK(fd, &c, 1)) {
            return 0;
        }

        DoExtension(fd, c, &Transparent, &ZeroDataBlock);
        continue;
    }

    if(c != ',') { /* Not a valid start character */
        continue;
    }

    /*1.4//++imageCount; */

    if(!ReadOK(fd, buf, 9)) {
        return 0;
    }

    useGlobalColormap = !BitSet(buf[8], LOCALCOLORMAP);

    bitPixel = 1 << ((buf[8] & 0x07) + 1);
    left = LM_to_uint(buf[0], buf[1]);
    top = LM_to_uint(buf[2], buf[3]);
    width = LM_to_uint(buf[4], buf[5]);
    height = LM_to_uint(buf[6], buf[7]);

    if(((left + width) > screen_width) || ((top + height) > screen_height)) {
        if(VERBOSE) {
            printf("Frame is not confined to screen dimension.\n");
        }
        return 0;
    }

    if(!(im = gdImageCreate(width, height))) {
        return 0;
    }

    im->interlace = BitSet(buf[8], INTERLACE);
    if(!useGlobalColormap) {
        if(ReadColorMap(fd, bitPixel, localColorMap)) {
            gdImageDestroy(im);
            return 0;
        }

        ReadImage(im, fd, width, height, localColorMap, BitSet(buf[8], INTERLACE), &ZeroDataBlock);
    } else {
        if(!haveGlobalColormap) {
            gdImageDestroy(im);
            return 0;
        }

        ReadImage(im, fd, width, height, ColorMap, BitSet(buf[8], INTERLACE), &ZeroDataBlock);
    }

    if(Transparent != (-1)) {
        gdImageColorTransparent(im, Transparent);
    }

    goto terminated;
}

goto完成了循环,甚至没有尝试读取另一帧。

这是因为此实现旨在从gif中显式读取一帧。只能一个

我在这个图书馆工作。也有其他缺陷。 PNG文件的透明性是7位,而不是8位(这是我使用它并稍后丢弃的主要原因之一)。

您可以将animated gifsgdImageGifAnimBegin(gdImagePtr im, FILE *outFile, int GlobalCM, int Loops)一起打包

[TL; DR] :libgd在加载时没有多帧选项。它不打算加载动画gif。