我有一个用来处理各种图像文件的程序。当前,它仅适用于静态图像。我想提供对gif的支持,并且我一直在寻找乏味的doc u ment a tion,但找不到任何有关如何逐帧操作gif的参考。
理想情况下,我想一次遍历gif,使用其他功能操纵文件中的每个帧,然后重新包装图像。
答案 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 gifs与gdImageGifAnimBegin(gdImagePtr im, FILE *outFile, int GlobalCM, int Loops)
一起打包
[TL; DR] :libgd在加载时没有多帧选项。它不打算加载动画gif。