音视频入门-20-BMP、PNG、JPG、GIF静态图生成GIF动态图 (3)

将静态图转成 RGB 以后,就可以根据 【19-使用giflib处理GIF图片】 使用 giflib 将 RGB 编码成 GIF 动态图。

完整步骤 #include <stdio.h> ...... int decodeBMP(char *, unsigned char **); int decodePNG(char *, unsigned char **); int decodeJPG(char *, unsigned char **); int decodeGIF(char *, unsigned char **); int encodeGIF(unsigned char **RGBBuffers, int NumOfRGBBuffer, char *GIFFileName, int ExpNumOfColors, int Width, int Height); int main() { char *bmp = "/Users/staff/Desktop/Android.bmp"; char *png = "/Users/staff/Desktop/Huawei.png"; char *jpg = "/Users/staff/Desktop/Fuchsia.jpg"; char *gif = "/Users/staff/Desktop/iOS.gif"; unsigned char *bmpRGB = NULL; unsigned char *pngRGB = NULL; unsigned char *jpgRGB = NULL; unsigned char *gifRGB = NULL; printf("开始解码 BMP 文件!\n"); decodeBMP(bmp, &bmpRGB); char *androidRGB = "/Users/staff/Desktop/Android.rgb"; FILE *androidRGBFile = fopen(androidRGB, "wb"); fwrite(bmpRGB, 400*400*3, 1, androidRGBFile); fclose(androidRGBFile); printf("\n\n"); printf("开始解码 PNG 文件!\n"); decodePNG(png, &pngRGB); char *huaweiRGB = "/Users/staff/Desktop/Huawei.rgb"; FILE *huaweiRGBFile = fopen(huaweiRGB, "wb"); fwrite(pngRGB, 400*400*3, 1, huaweiRGBFile); fclose(huaweiRGBFile); printf("\n\n"); printf("开始解码 JPG 文件!\n"); decodeJPG(jpg, &jpgRGB); char *fuchsiaRGB = "/Users/staff/Desktop/Fuchsia.rgb"; FILE *fuchsiaRGBFile = fopen(fuchsiaRGB, "wb"); fwrite(jpgRGB, 400*400*3, 1, fuchsiaRGBFile); fclose(fuchsiaRGBFile); printf("\n\n"); printf("开始解码 GIF 文件!\n"); decodeGIF(gif, &gifRGB); char *iOSRGB = "/Users/staff/Desktop/iOS.rgb"; FILE *iOSRGBFile = fopen(iOSRGB, "wb"); fwrite(gifRGB, 400*400*3, 1, iOSRGBFile); fclose(iOSRGBFile); printf("\n\n"); unsigned char **rgbBuffers = malloc(4*sizeof(unsigned char *)); rgbBuffers[0] = bmpRGB; rgbBuffers[1] = pngRGB; rgbBuffers[2] = jpgRGB; rgbBuffers[3] = gifRGB; encodeGIF(rgbBuffers, 4, "/Users/staff/Desktop/image-to-gif.gif", 7, 400, 400); free(bmpRGB); free(pngRGB); free(jpgRGB); free(gifRGB); return 0; } int decodeBMP(char *filename, unsigned char **bmpRGB) { ...... } int decodePNG(char *filename, unsigned char **pngRGB) { ...... } int decodeJPG(char *filename, unsigned char **jpgRGB) { ...... } int decodeGIF(char *filename, unsigned char **gifRGB) { ...... } int encodeGIF(unsigned char **RGBBuffers, int NumOfRGBBuffer, char *GIFFileName, ...... }

将 RGB 编码成 GIF 的方法 encodeGIF:

int encodeGIF(unsigned char **RGBBuffers, int NumOfRGBBuffer, char *GIFFileName, int ExpNumOfColors, int Width, int Height) { int ColorMapSize; GifByteType *RedBuffer = NULL, *GreenBuffer = NULL, *BlueBuffer = NULL, *OutputBuffer = NULL; ColorMapObject *OutputColorMap = NULL; // 打开输出的 GIF 文件 int Error; GifFileType *GifFile; if ((GifFile = EGifOpenFileName(GIFFileName, false, &Error)) == NULL) { PrintGifError(Error); printf("EGifOpenFileName Error.\n"); return -1; } GifFile->SWidth = Width; GifFile->SHeight = Height; GifFile->SColorResolution = 1; GifFile->SBackGroundColor = 0; GifFile->SColorMap = NULL; unsigned long Size; GifByteType *RedP, *GreenP, *BlueP; GifByteType *Buffer, *BufferP; Size = ((long) Width) * Height * sizeof(GifByteType); if ((RedBuffer = (GifByteType *) malloc((unsigned int) Size)) == NULL || (GreenBuffer = (GifByteType *) malloc((unsigned int) Size)) == NULL || (BlueBuffer = (GifByteType *) malloc((unsigned int) Size)) == NULL) { return -1; } if ((Buffer = (GifByteType *) malloc(Width * 3)) == NULL) { return -1; } for(int i = 0; i < NumOfRGBBuffer; i++) { ColorMapSize = 1 << ExpNumOfColors; RedP = RedBuffer; GreenP = GreenBuffer; BlueP = BlueBuffer; int pointer = 0; for (int j = 0; j < Height; j++) { int k; memcpy(Buffer, RGBBuffers[i]+pointer, Width * 3); pointer+=Width*3; for (k = 0, BufferP = Buffer; k < Width; k++) { *RedP++ = *BufferP++; *GreenP++ = *BufferP++; *BlueP++ = *BufferP++; } } if ((OutputColorMap = GifMakeMapObject(ColorMapSize, NULL)) == NULL || (OutputBuffer = (GifByteType *) malloc(Width * Height * sizeof(GifByteType))) == NULL) { printf("Failed to allocate memory required, aborted.\n"); return -1; } if (GifQuantizeBuffer(Width, Height, &ColorMapSize, RedBuffer, GreenBuffer, BlueBuffer, OutputBuffer, OutputColorMap->Colors) == GIF_ERROR) { printf("GifQuantizeBuffer Error.\n"); return -1; } printf("MakeSavedImage:%d\n", i); SavedImage *image = GifMakeSavedImage(GifFile, NULL); GifImageDesc *imageDesc = (GifImageDesc *) malloc(sizeof(GifImageDesc)); imageDesc->Left = 0; imageDesc->Top = 0; imageDesc->Width = Width; imageDesc->Height = Height; imageDesc->Interlace = false; imageDesc->ColorMap = OutputColorMap; image->ImageDesc = *imageDesc; image->RasterBits = OutputBuffer; GraphicsControlBlock *GCB = (GraphicsControlBlock *) malloc(sizeof(GraphicsControlBlock)); GCB->DisposalMode = DISPOSAL_UNSPECIFIED; GCB->DelayTime = 100; GCB->UserInputFlag = false; GCB->TransparentColor = NO_TRANSPARENT_COLOR; printf("GCBToSaved:%d\n", i); EGifGCBToSavedExtension(GCB, GifFile, i); } free((char *) RedBuffer); free((char *) GreenBuffer); free((char *) BlueBuffer); printf("输出 GIF 文件。\n"); // 输出文件 EGifSpew(GifFile); return 0; } 查看 GIF

image-to-gif-preview.jpg

代码:
audio-video-blog-demos

参考资料:

【音视频入门-05-RGB-TO-BMP使用开源库】

【音视频入门-13-使用开源库生成PNG图片】

【音视频入门-16-使用libjpeg-trubo处理JPEG图片】

【音视频入门-19-使用giflib处理GIF图片】

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wssfsj.html