linux 透明图片,FreeImage 生成带透明通道的GIF

FreeImage 生成带透明通道的GIF

主要方法:

加载图像及读取参数

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

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;

}

原图:

ddaf5d5f9a6fe965239a47120ce664f6.png

bf557c80098d0993691405901accccfe.png

8895822164620c8574fd87b10cbab7e3.png

结果:

0738f65f84d983166d9b54444750bc2b.gif0b1331709591d260c1c78e86d0c51c18.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值