FreeImage 生成带透明通道的GIF
程序员文章站
2022-04-12 11:51:14
主要方法: 1. 加载图像及读取参数 FreeImage_Load FreeImage_GetWidth FreeImage_GetHeight FreeImage_Allocate FreeImage_GetPixelColor FreeImage_SetPixelColor 2. 保存GIF F ......
主要方法:
- 加载图像及读取参数
FreeImage_Load
FreeImage_GetWidth
FreeImage_GetHeight
FreeImage_Allocate
FreeImage_GetPixelColor
FreeImage_SetPixelColor - 保存GIF
FreeImage_OpenMultiBitmap
FreeImage_SetMetadata
FreeImage_SetTagXX
FreeImage_AppendPage - GIF 透明模板
FreeImage_ColorQuantize
FreeImage_GetPalette
FreeImage_SetTransparencyTable
这里需要注意的是,图像通道32位转24位时,不使用FreeImage_ConvertTo24Bits,而通过PNG透明通道进行数据复制,避免背景对后面生成透明表(FreeImage _SetTransparencyTable)造成干扰。此外,注意设置24位图的背景色,避免与表情区域颜色相近。
这里做了如下设置
// 蓝色 src_color.rgbRed = 0; src_color.rgbBlue = 255; src_color.rgbGreen = 0;
完整代码:
#include "FreeImagePlus.h" #include <iostream> using namespace std; FIBITMAP* genhDIB8bpp(FIBITMAP* hDIB32bpp); int main(int argc, char** argv[]) { FreeImage_Initialise(TRUE); // load source images FIBITMAP* hdib1 = FreeImage_Load(FIF_PNG, "img1.png", PNG_IGNOREGAMMA); FIBITMAP* hdib2 = FreeImage_Load(FIF_PNG, "img2.png", PNG_IGNOREGAMMA); FIBITMAP* hdib3 = FreeImage_Load(FIF_PNG, "img3.png", PNG_IGNOREGAMMA); if (NULL == hdib1 || NULL == hdib2 || NULL == hdib3) { cout << " load image(png) error. \n"; return -1; } int bpp1 = FreeImage_GetBPP(hdib1); int bpp2 = FreeImage_GetBPP(hdib2); int bpp3 = FreeImage_GetBPP(hdib3); int dib_type = FreeImage_GetImageType(hdib1); cout << "Type: " << dib_type << " " << FIT_BITMAP << endl; cout << "BPP: " << bpp1 << " " << bpp2 << " " << bpp3 << endl; if (32 != bpp1 || 32 != bpp2 || 32 != bpp3) return -1; bool bMemoryCache = TRUE; FIMULTIBITMAP *multi = FreeImage_OpenMultiBitmap(FIF_GIF, "out.gif", TRUE, FALSE); int fps = 3; DWORD dwFrameTime = (DWORD)((1000.0f / fps) + 0.5f); cout << "gen hDIB8bpp " << endl; FIBITMAP* dib[3]; dib[0] = genhDIB8bpp(hdib1); dib[1] = genhDIB8bpp(hdib2); dib[2] = genhDIB8bpp(hdib3); cout << "AppendPage" << endl; for (int i = 0; i < 3; i++ ){ // clear any animation metadata used by this dib as we’ll adding our own ones FreeImage_SetMetadata(FIMD_ANIMATION, dib[i], NULL, NULL); // add animation tags to dib[i] FITAG *tag = FreeImage_CreateTag(); if (tag) { FreeImage_SetTagKey(tag, "FrameTime"); FreeImage_SetTagType(tag, FIDT_LONG); FreeImage_SetTagCount(tag, 1); FreeImage_SetTagLength(tag, 4); FreeImage_SetTagValue(tag, &dwFrameTime); FreeImage_SetMetadata(FIMD_ANIMATION, dib[i], FreeImage_GetTagKey(tag), tag); FreeImage_DeleteTag(tag); } FreeImage_AppendPage(multi, dib[i]); // FreeImage_Unload(dib[i]); } FreeImage_CloseMultiBitmap(multi); FreeImage_Unload(dib[0]); FreeImage_Unload(dib[1]); FreeImage_Unload(dib[2]); FreeImage_Unload(hdib1); FreeImage_Unload(hdib2); FreeImage_Unload(hdib3); FreeImage_DeInitialise(); return 0; } FIBITMAP* genhDIB8bpp(FIBITMAP* hDIB32bpp) { FIBITMAP* hDIB8bpp = NULL; int w = FreeImage_GetWidth(hDIB32bpp); int h = FreeImage_GetHeight(hDIB32bpp); // FIBITMAP *hDIB24bpp = FreeImage_ConvertTo24Bits(hDIB32bpp); FIBITMAP *hDIB24bpp = FreeImage_Allocate(w, h, 24); for (int i = h - 1; i >= 0; i--) for (int j = 0; j < w; j++) { RGBQUAD src_color; FreeImage_GetPixelColor(hDIB32bpp, j, i, &src_color); if ( 255 == src_color.rgbReserved ) FreeImage_SetPixelColor(hDIB24bpp, j, i, &src_color); else { src_color.rgbRed = 0; src_color.rgbBlue = 255; src_color.rgbGreen = 0; FreeImage_SetPixelColor(hDIB24bpp, j, i, &src_color); } } FreeImage_Save(FIF_JPEG, hDIB24bpp, "out.jpg"); BYTE Transparency[256]; if (!hDIB8bpp) hDIB8bpp = FreeImage_ColorQuantize(hDIB24bpp, FIQ_WUQUANT); RGBQUAD *Palette = FreeImage_GetPalette(hDIB8bpp); for (int i = 0; i < 256; i++) { Transparency[i] = 0xFF; if (Palette[i].rgbRed != 0x00 && Palette[i].rgbBlue != 0xFF && Palette[i].rgbGreen > 0x00) { Transparency[i] = 0x00; } } FreeImage_SetTransparencyTable(hDIB8bpp, Transparency, 256); // FreeImage_Save(FIF_PNG, hDIB8bpp, "out.png"); FreeImage_Unload(hDIB24bpp); return hDIB8bpp; }
原图:
结果:
上一篇: Vue.js 2.x:组件的定义和注册(详细的图文教程)
下一篇: 智能相机中的HDR功能有何效果?