主要方法:

  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位图的背景色,避免与表情区域颜色相近。

这里做了如下设置

  1. src_color.rgbRed = 0;
  2. src_color.rgbBlue = 255;
  3. src_color.rgbGreen = 0;

完整代码:

  1. #include "FreeImagePlus.h"
  2. #include <iostream>
  3. using namespace std;
  4. FIBITMAP* genhDIB8bpp(FIBITMAP* hDIB32bpp);
  5. int main(int argc, char** argv[])
  6. {
  7. FreeImage_Initialise(TRUE);
  8. // load source images
  9. FIBITMAP* hdib1 = FreeImage_Load(FIF_PNG, "img1.png", PNG_IGNOREGAMMA);
  10. FIBITMAP* hdib2 = FreeImage_Load(FIF_PNG, "img2.png", PNG_IGNOREGAMMA);
  11. FIBITMAP* hdib3 = FreeImage_Load(FIF_PNG, "img3.png", PNG_IGNOREGAMMA);
  12. if (NULL == hdib1 || NULL == hdib2 || NULL == hdib3)
  13. {
  14. cout << " load image(png) error. \n";
  15. return -1;
  16. }
  17. int bpp1 = FreeImage_GetBPP(hdib1);
  18. int bpp2 = FreeImage_GetBPP(hdib2);
  19. int bpp3 = FreeImage_GetBPP(hdib3);
  20. int dib_type = FreeImage_GetImageType(hdib1);
  21. cout << "Type: " << dib_type << " " << FIT_BITMAP << endl;
  22. cout << "BPP: " << bpp1 << " " << bpp2 << " " << bpp3 << endl;
  23. if (32 != bpp1 || 32 != bpp2 || 32 != bpp3)
  24. return -1;
  25. bool bMemoryCache = TRUE;
  26. FIMULTIBITMAP *multi = FreeImage_OpenMultiBitmap(FIF_GIF, "out.gif", TRUE, FALSE);
  27. int fps = 3;
  28. DWORD dwFrameTime = (DWORD)((1000.0f / fps) + 0.5f);
  29. cout << "gen hDIB8bpp " << endl;
  30. FIBITMAP* dib[3];
  31. dib[0] = genhDIB8bpp(hdib1);
  32. dib[1] = genhDIB8bpp(hdib2);
  33. dib[2] = genhDIB8bpp(hdib3);
  34. cout << "AppendPage" << endl;
  35. for (int i = 0; i < 3; i++ ){
  36. // clear any animation metadata used by this dib as we’ll adding our own ones
  37. FreeImage_SetMetadata(FIMD_ANIMATION, dib[i], NULL, NULL);
  38. // add animation tags to dib[i]
  39. FITAG *tag = FreeImage_CreateTag();
  40. if (tag) {
  41. FreeImage_SetTagKey(tag, "FrameTime");
  42. FreeImage_SetTagType(tag, FIDT_LONG);
  43. FreeImage_SetTagCount(tag, 1);
  44. FreeImage_SetTagLength(tag, 4);
  45. FreeImage_SetTagValue(tag, &dwFrameTime);
  46. FreeImage_SetMetadata(FIMD_ANIMATION, dib[i], FreeImage_GetTagKey(tag), tag);
  47. FreeImage_DeleteTag(tag);
  48. }
  49. FreeImage_AppendPage(multi, dib[i]);
  50. // FreeImage_Unload(dib[i]);
  51. }
  52. FreeImage_CloseMultiBitmap(multi);
  53. FreeImage_Unload(dib[0]);
  54. FreeImage_Unload(dib[1]);
  55. FreeImage_Unload(dib[2]);
  56. FreeImage_Unload(hdib1);
  57. FreeImage_Unload(hdib2);
  58. FreeImage_Unload(hdib3);
  59. FreeImage_DeInitialise();
  60. return 0;
  61. }
  62. FIBITMAP* genhDIB8bpp(FIBITMAP* hDIB32bpp)
  63. {
  64. FIBITMAP* hDIB8bpp = NULL;
  65. int w = FreeImage_GetWidth(hDIB32bpp);
  66. int h = FreeImage_GetHeight(hDIB32bpp);
  67. // FIBITMAP *hDIB24bpp = FreeImage_ConvertTo24Bits(hDIB32bpp);
  68. FIBITMAP *hDIB24bpp = FreeImage_Allocate(w, h, 24);
  69. for (int i = h - 1; i >= 0; i--)
  70. for (int j = 0; j < w; j++)
  71. {
  72. RGBQUAD src_color;
  73. FreeImage_GetPixelColor(hDIB32bpp, j, i, &src_color);
  74. if ( 255 == src_color.rgbReserved )
  75. FreeImage_SetPixelColor(hDIB24bpp, j, i, &src_color);
  76. else
  77. {
  78. src_color.rgbRed = 0;
  79. src_color.rgbBlue = 255; src_color.rgbGreen = 0;
  80. FreeImage_SetPixelColor(hDIB24bpp, j, i, &src_color);
  81. }
  82. }
  83. FreeImage_Save(FIF_JPEG, hDIB24bpp, "out.jpg");
  84. BYTE Transparency[256];
  85. if (!hDIB8bpp)
  86. hDIB8bpp = FreeImage_ColorQuantize(hDIB24bpp, FIQ_WUQUANT);
  87. RGBQUAD *Palette = FreeImage_GetPalette(hDIB8bpp);
  88. for (int i = 0; i < 256; i++)
  89. {
  90. Transparency[i] = 0xFF;
  91. if (Palette[i].rgbRed != 0x00 && Palette[i].rgbBlue != 0xFF && Palette[i].rgbGreen > 0x00)
  92. {
  93. Transparency[i] = 0x00;
  94. }
  95. }
  96. FreeImage_SetTransparencyTable(hDIB8bpp, Transparency, 256);
  97. // FreeImage_Save(FIF_PNG, hDIB8bpp, "out.png");
  98. FreeImage_Unload(hDIB24bpp);
  99. return hDIB8bpp;
  100. }

原图:

结果:

FreeImage 生成带透明通道的GIF的更多相关文章

  1. javascript播放带透明通道的mp4动画

    随着互联网的发展,动画效果也在一直更新,从刚开始的flsh动画,cocos骨骼动画,到YY开源的svga动画.最近1年来,带有透明通道的mp4动画被使用的极为广泛,对于app端.github上有开源的 ...

  2. Photoshop做32位带Alpha通道的bmp图片

    原文链接: http://blog.sina.com.cn/s/blog_65c0cae801016e5u.html   批量制作32位带Alpha通道的bmp图片,可以制作一个动作,内容可以如下: ...

  3. BMP是可以保存alpha通道的。

    一直以来都不太熟悉BMP格式,今天保存图片的时候发现bmp是可以保存透明通道的,突然想起来以前下载的一些游戏素材贴图里面就有一些bmp格式的贴图.记录一下.

  4. C#生成带logo的二维码

    带logo的二维码生成分为两步骤:首先根据输入的内容生成二维码图片,然后读取本地的logo图片,通过图片处理生成带logo的二维码. 生成的二维码效果如下: 下面直接贴出二维码生成类   QRCode ...

  5. js生成带参的二维码

    最近项目中有需求生成带参的二维码,考虑过用JAVA后台生成返回前端展示,后面了解到用jquery的qrcode.js插件可以很好现实 引入js: require.config({ baseUrl : ...

  6. .NET生成带Logo的二维码

    使用ThoughtWorks.QRCode生成,利用这个库来生成带Logo的二维码(就是中间嵌了一个图片的二维码),直接见代码: HttpContext context = HttpContext.C ...

  7. Force.com微信开发系列(八)生成带参数的二维码

    为了满足用户渠道推广分析的需要,公众平台提供了生成带二维码的接口.使用该接口可以获得多个带不同场景值的二维码,用户扫描后,公众号可以接收到事件推送.目前有两种类型的二维码,分别是临时二维码和永久二维码 ...

  8. PowerDesigner15.1创建模型及生成带注释sql操作手册

    转自:http://blog.csdn.net/huiwenjie168/article/details/7824029 一.创建模型 操作:file-->new Model… 快捷键:ctrl ...

  9. java生成带html样式的word文件

    参考:http://blog.csdn.net/xiexl/article/details/6652230 最近在项目中需要将通过富文本编辑器处理过的文字转换为Word,查了很久,大家通常的解决办法是 ...

随机推荐

  1. iview框架下,modal内容过长,select选项位置不对

    问题 modal组件中内容过长,超过一屏,有滚动条后,里面包含的select组件选项内容,位置会不对 解决 在使用select的时候添加transfer属性

  2. Java全系列帮助文档下载

    JDK(Java Development Kit,Java开发包,Java开发工具)是一个写Java的applet和应用程序的程序开发环境.它由一个处于操作系统层之上的运行环境还有开发者编译,调试和运 ...

  3. Day04——Python模块

    一.模块简介 模块是实现了某个功能的代码集合,比如几个.py文件可以组成代码集合即模块.其中常见的模块有os模块(系统相关),file模块(文件操作相关) 模块主要分三类: 自定义模块 :所谓自定义模 ...

  4. easyui学习笔记6—基本的Accordion(手风琴)

    手风琴也是web页面中常见的一个控件,常常用在网站后台管理中,这里我们看看easyui中基本的手风琴设置. 1.先看看引用的资源 <meta charset="UTF-8" ...

  5. [EffectiveC++]item36:绝不重新定义继承而来的non-virtual函数

  6. EOF及相关函数

    结论:EOF是在头文件stdio.h中预定义的一个宏,而eof(end of file)是一个与标准输入/输出流相关联的标志位.当文件指针已经指向文件尾且再次尝试读取时,eof标志会被设置.同时,某些 ...

  7. C# using、namespace使用注意事项

    一.using 用法 1.引用命名空间. 如: using System; 2.自动释放对象使用的资源. 如: using (SqlConnection connection = new SqlCon ...

  8. Junit4所需jar包

    在eclipse中新建一个Junit类,运行时出现java.lang.NoClassdeffounderror:org/apache/commons/logging/LogFactory错误,原来是缺 ...

  9. bzoj3718 [PA2014]Parking

    Description 你的老板命令你将停车场里的车移动成他想要的样子.停车场是一个长条矩形,宽度为w.我们以其左下角顶点为原点,坐标轴平行于矩形的边,建立直角坐标系.停车场很长,我们可以认为它一直向 ...

  10. The Relationship Between Layers and Views

    Layers provide infrastructure for your views. 内核与外壳:数据与封装的关系.