linuxsir首页 LinuxSir.Org | Linux、BSD、Solaris、Unix | 开源传万世,因有我参与欢迎您!
网站首页 | 设为首页 | 加入收藏
您所在的位置:主页 > Linux及计算机学科基础理论版 >

FreeImage 生成带透明通道的GIF

时间:2018-06-23  来源:未知  作者:admin666

FreeImage 生成带透明通道的GIF

主要方法:

  1. 加载图像及读取参数
    FreeImage_Load
    FreeImage_GetWidth
    FreeImage_GetHeight
    FreeImage_Allocate
    FreeImage_GetPixelColor
    FreeImage_SetPixelColor
  2. 保存GIF
    FreeImage_OpenMultiBitmap
    FreeImage_SetMetadata
    FreeImage_SetTagXX
    FreeImage_AppendPage
  3. 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[])
{
  &n救命解药bsp; FreeImage_Initialise(TRUE);
  &n救命解药bsp; // load source images
  &n救命解药bsp; FIBITMAP* hdib1 = FreeImage_Load(FIF_PNG, "img1.png", PNG_IGNOREGAMMA);
  &n救命解药bsp; FIBITMAP* hdib2 = FreeImage_Load(FIF_PNG, "img2.png", PNG_IGNOREGAMMA);
  &n救命解药bsp; FIBITMAP* hdib3 = FreeImage_Load(FIF_PNG, "img3.png", PNG_IGNOREGAMMA);

  &n救命解药bsp; if (NULL == hdib1 || NULL == hdib2 || NULL == hdib3)
  &n救命解药bsp; {
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; cout << " load  image(png) error. \n";
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; return -1;
  &n救命解药bsp; }

  &n救命解药bsp; int bpp1 = FreeImage_GetBPP(hdib1);
  &n救命解药bsp; int bpp2 = FreeImage_GetBPP(hdib2);
  &n救命解药bsp; int bpp3 = FreeImage_GetBPP(hdib3);
  &n救命解药bsp;
  &n救命解药bsp; int dib_type = FreeImage_GetImageType(hdib1);
  &n救命解药bsp; cout << "Type: " << dib_type << " " << FIT_BITMAP  << endl;
  &n救命解药bsp; cout << "BPP: " << bpp1 << " " << bpp2 << " " << bpp3 << endl;
  &n救命解药bsp; if (32 != bpp1 || 32 != bpp2 || 32 != bpp3)
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; return -1;
  &n救命解药bsp;

  &n救命解药bsp; bool bMemoryCache = TRUE;

  &n救命解药bsp; FIMULTIBITMAP *multi = FreeImage_OpenMultiBitmap(FIF_GIF, "out.gif", TRUE, FALSE);
  &n救命解药bsp; int fps = 3;
  &n救命解药bsp; DWORD dwFrameTime = (DWORD)((1000.0f / fps) + 0.5f);

  &n救命解药bsp; cout << "gen hDIB8bpp " << endl;
  &n救命解药bsp; FIBITMAP* dib[3];
  &n救命解药bsp; dib[0] = genhDIB8bpp(hdib1);
  &n救命解药bsp; dib[1] = genhDIB8bpp(hdib2);
  &n救命解药bsp; dib[2] = genhDIB8bpp(hdib3);

  &n救命解药bsp; cout << "AppendPage" << endl;
  &n救命解药bsp; for (int i = 0; i < 3; i++ ){
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; // clear any animation metadata used by this dib as we’ll adding our own ones
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; FreeImage_SetMetadata(FIMD_ANIMATION, dib[i], NULL, NULL);
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; // add animation tags to dib[i]
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; FITAG *tag = FreeImage_CreateTag();
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; if (tag) {
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; FreeImage_SetTagKey(tag, "FrameTime");
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; FreeImage_SetTagType(tag, FIDT_LONG);
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; FreeImage_SetTagCount(tag, 1);
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; FreeImage_SetTagLength(tag, 4);
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; FreeImage_SetTagValue(tag, &dwFrameTime);
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; FreeImage_SetMetadata(FIMD_ANIMATION, dib[i], FreeImage_GetTagKey(tag), tag);
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; FreeImage_DeleteTag(tag);
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; }
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; FreeImage_AppendPage(multi, dib[i]);
//  &n救命解药bsp; &n救命解药bsp; FreeImage_Unload(dib[i]);
  &n救命解药bsp; }
  &n救命解药bsp; FreeImage_CloseMultiBitmap(multi);

  &n救命解药bsp; FreeImage_Unload(dib[0]);
  &n救命解药bsp; FreeImage_Unload(dib[1]);
  &n救命解药bsp; FreeImage_Unload(dib[2]);
  &n救命解药bsp;
  &n救命解药bsp; FreeImage_Unload(hdib1);
  &n救命解药bsp; FreeImage_Unload(hdib2);
  &n救命解药bsp; FreeImage_Unload(hdib3);

  &n救命解药bsp; FreeImage_DeInitialise();
  &n救命解药bsp; return 0;
}

FIBITMAP* genhDIB8bpp(FIBITMAP* hDIB32bpp)
{
  &n救命解药bsp; FIBITMAP* hDIB8bpp = NULL;
  &n救命解药bsp; int w = FreeImage_GetWidth(hDIB32bpp);
  &n救命解药bsp; int h = FreeImage_GetHeight(hDIB32bpp);

//  FIBITMAP *hDIB24bpp  = FreeImage_ConvertTo24Bits(hDIB32bpp);
  &n救命解药bsp; FIBITMAP *hDIB24bpp = FreeImage_Allocate(w, h, 24);
  &n救命解药bsp; for (int i = h - 1; i >= 0; i--)
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; for (int j = 0; j < w; j++)
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; {
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; RGBQUAD src_color;
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; FreeImage_GetPixelColor(hDIB32bpp, j, i, &src_color);
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; if ( 255 == src_color.rgbReserved )
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; FreeImage_SetPixelColor(hDIB24bpp, j, i, &src_color);
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; else
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; {
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; src_color.rgbRed = 0;
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; src_color.rgbBlue = 255; src_color.rgbGreen = 0;
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; FreeImage_SetPixelColor(hDIB24bpp, j, i, &src_color);
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; }
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; }
  &n救命解药bsp; FreeImage_Save(FIF_JPEG, hDIB24bpp, "out.jpg");

  &n救命解药bsp; BYTE  Transparency[256];
  &n救命解药bsp; if (!hDIB8bpp)
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; hDIB8bpp = FreeImage_ColorQuantize(hDIB24bpp, FIQ_WUQUANT);

  &n救命解药bsp; RGBQUAD *Palette = FreeImage_GetPalette(hDIB8bpp);
  &n救命解药bsp; for (int i = 0; i < 256; i++)
  &n救命解药bsp; {
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; Transparency[i] = 0xFF;
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; if (Palette[i].rgbRed != 0x00 && Palette[i].rgbBlue != 0xFF && Palette[i].rgbGreen > 0x00)
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; {
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; Transparency[i] = 0x00;
  &n救命解药bsp; &n救命解药bsp; &n救命解药bsp; }
  &n救命解药bsp; }

  &n救命解药bsp; FreeImage_SetTransparencyTable(hDIB8bpp, Transparency, 256);

//  FreeImage_Save(FIF_PNG, hDIB8bpp, "out.png");
  &n救命解药bsp; FreeImage_Unload(hDIB24bpp);

  &n救命解药bsp; return hDIB8bpp;
}

原图:

结果:

linux
友情链接