下面,使用 GIFLIB 分离出 GIF 每一帧的 RGB ,然后将分离出的 RGB 再合成 GIF。
GIF to RGBGIFLIB 项目里的 gif2rgb.c 已经实现了解码 GIF -> RGB。不过 gif2rgb.c 只保存了最后一帧图片的 RGB,这里需要改造。
gif2rgb.cgif2rgb.c 在 GIF2RGB 方法最后才调用 DumpScreen2RGB 保存 RGB。
...... static void DumpScreen2RGB(char *FileName, ColorMapObject *ColorMap, GifRowType *ScreenBuffer, int ScreenWidth, int ScreenHeight) { ...... } static void GIF2RGB(int NumFiles, char *FileName, bool OneFileFlag, char *OutFileName) { ...... /* Scan the content of the GIF file and load the image(s) in: */ do { ...... } while (RecordType != TERMINATE_RECORD_TYPE); /* Lets dump it - set the global variables required and do it: */ ColorMap = (GifFile->Image.ColorMap ? GifFile->Image.ColorMap : GifFile->SColorMap); if (ColorMap == NULL) { fprintf(stderr, "Gif Image does not have a colormap\n"); exit(EXIT_FAILURE); } /* check that the background color isn't garbage (SF bug #87) */ if (GifFile->SBackGroundColor < 0 || GifFile->SBackGroundColor >= ColorMap->ColorCount) { fprintf(stderr, "Background color out of range for colormap\n"); exit(EXIT_FAILURE); } DumpScreen2RGB(OutFileName, OneFileFlag, ColorMap, ScreenBuffer, GifFile->SWidth, GifFile->SHeight); (void)free(ScreenBuffer); if (DGifCloseFile(GifFile, &Error) == GIF_ERROR) { PrintGifError(Error); exit(EXIT_FAILURE); } } gif-to-rgb-library.c需要把调用 DumpScreen2RGB 的位置移到循环体内 case IMAGE_DESC_RECORD_TYPE: 位置。
...... static void DumpScreen2RGB(char *FileName, ColorMapObject *ColorMap, GifRowType *ScreenBuffer, int ScreenWidth, int ScreenHeight) { ...... } static void GIF2RGB( char *FileName, char *OutFileNamePattern) { ...... do { ...... switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: ...... ColorMap = (GifFile->Image.ColorMap ? GifFile->Image.ColorMap : GifFile->SColorMap); if (ColorMap == NULL) { fprintf(stderr, "Gif Image does not have a colormap\n"); exit(EXIT_FAILURE); } /* check that the background color isn't garbage (SF bug #87) */ if (GifFile->SBackGroundColor < 0 || GifFile->SBackGroundColor >= ColorMap->ColorCount) { fprintf(stderr, "Background color out of range for colormap\n"); exit(EXIT_FAILURE); } char *name = malloc(255*sizeof(char)); sprintf(name, OutFileNamePattern, screenIndex++); printf("Final File Name: %s\n", name); DumpScreen2RGB(name, ColorMap, ScreenBuffer, GifFile->SWidth, GifFile->SHeight); break; case EXTENSION_RECORD_TYPE: ...... } } while (RecordType != TERMINATE_RECORD_TYPE); ...... } int main(int argc, char **argv) { GIF2RGB( "/Users/staff/Desktop/rainbow.gif", "/Users/staff/Desktop/rainbow-%d.rgb"); return 0; } 查看 GIF -> RGB 结果根据 【手动生成一张GIF图片】 生成的 GIF rainbow.gif 含有 7 个图像,所以会得到 7 个 .RGB 文件。
ffplay 查看 RGB 文件:
ffplay -f rawvideo -pixel_format rgb24 -s 700x700 rainbow-0.rgb ffplay -f rawvideo -pixel_format rgb24 -s 700x700 rainbow-1.rgb ffplay -f rawvideo -pixel_format rgb24 -s 700x700 rainbow-2.rgb ffplay -f rawvideo -pixel_format rgb24 -s 700x700 rainbow-3.rgb ffplay -f rawvideo -pixel_format rgb24 -s 700x700 rainbow-4.rgb ffplay -f rawvideo -pixel_format rgb24 -s 700x700 rainbow-5.rgb ffplay -f rawvideo -pixel_format rgb24 -s 700x700 rainbow-6.rgb RGB to GIF上面,从 rainbow.gif 中提取出了 7 个 RGB 文件。
下面,读取这 7 个 RGB 文件,使用 GIFLIB 编码成 GIF 动态图。
成功实现了 GIF -> RGB(s) -> GIF。
代码:
audio-video-blog-demos
参考资料:
图像解码之三——giflib解码gif图片
How do I get the RGB colour data from a GIFLIB SavedImage structure