声明:所有权利保留。

转载必须说明出处:http://blog.csdn.net/cartzhang/article/details/44020175

近来需要把BMP或Kinect的内存图片多张合成为小GIF图片。找了找,东西不少,做个小结,以备以后用到。

一、GIF.h

此方法很简单,就是一个头文件。但是我没有尝试成功。可能的原因是我的BMP图片的生成字节顺序与GIF.H头文件所要求的不一致。

Gif.h头文件代码如下:

使用方法如下:

[cpp]  view plain  copy
  1. //GifWriter m_gif_writer;
  2. //char* file_name = "E:\\aaa.gif";
  3. //int width = 128;
  4. //int height = 128;
  5. //int delay = 10;
  6. //GifBegin(&m_gif_writer, file_name, width, height, delay);
  7. // 代码里面自动从第一帧开始。只第一帧添加GIF的头信息
  8. //for ()
  9. //{
  10. GifWriteFrame()
  11. //}
  12. //GifEnd()

头文件出处出处:作者:Charlie Tangora

github 地址:https://github.com/ginsweater/gif-h

二、CXimage 库

此库开源,可随便下载。

使用下载的版本为702full版本。Vs2013编译很顺利,因为需要使用的64位版本,所以使用了x64的release模式。有个与mfc相关的编译不过,直接无视了,本人用不上mfc。

生成的为lib的静态库。

我把所需要的头文件和静态库拷贝的到自己建立的目录下和各个对应的文件夹下,如图:

Include 文件从CXimage中拷贝头文件,lib库文件为编译后生成的x64文件里面的,包括Debug版本和Release版本。

网上找了个代码,对CXimage的GIF写了两个函数。本人在基础上稍微添加和修改了代码。

其实主要是处理相关文件夹方便来调用的。非常感谢网友提供,头文件和CPP文件如下:(文件出处为:http://blog.csdn.net/fengbingchun/article/details/43538081

若有问题,请随时联系,非常感谢!)

mGif.h头文件:

[cpp]  view plain  copy
  1. #pragma once
  2. #ifndef _MGIF_H__
  3. #define _MGIF_H__
  4. #include <string>
  5. using namespace std;
  6. void decoding_gif(string strGifName, string strSavePath);
  7. void encoding_gif(string strImgPath, string strGifName);
  8. #endif //

mGif.CPP文件:

[cpp]  view plain  copy
  1. //Cartzhang
  2. #include "mGif.h"
  3. #include "stdafx.h"
  4. #include "mGif.h"
  5. #include <iostream>
  6. #include "ximagif.h"
  7. #include <io.h>
  8. using namespace std;
  9. std::wstring s2ws(const std::string& s)
  10. {
  11. int len;
  12. int slength = (int)s.length() + 1;
  13. len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
  14. wchar_t* buf = new wchar_t[len];
  15. MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
  16. std::wstring r(buf);
  17. delete[] buf;
  18. return r;
  19. }
  20. void decoding_gif(string strGifName, string strSavePath)
  21. {
  22. CxImage img;
  23. std::wstring stemp = s2ws(strGifName); // Temporary buffer is required
  24. LPCWSTR PicName = stemp.c_str();
  25. img.Load(PicName, CXIMAGE_FORMAT_GIF);
  26. int iNumFrames = img.GetNumFrames();
  27. cout << "frames num = " << iNumFrames << endl;
  28. CxImage* newImage = new CxImage();
  29. for (int i = 0; i < iNumFrames; i++) {
  30. newImage->SetFrame(i);
  31. newImage->Load(PicName, CXIMAGE_FORMAT_GIF);
  32. char tmp[64];
  33. sprintf(tmp, "%d", i);
  34. string tmp1;
  35. tmp1 = tmp1.insert(0, tmp);
  36. tmp1 = strSavePath + tmp1 + ".png";
  37. stemp = s2ws(tmp1); // Temporary buffer is required
  38. PicName = stemp.c_str();
  39. newImage->Save(PicName, CXIMAGE_FORMAT_PNG);
  40. }
  41. if (newImage) delete newImage;
  42. }
  43. int TraverseFolder(const string strFilePath, string strImageNameSets[])
  44. {
  45. int iImageCount = 0;
  46. _finddata_t fileInfo;
  47. long handle = _findfirst(strFilePath.c_str(), &fileInfo);
  48. if (handle == -1L) {
  49. cerr << "failed to transfer files" << endl;
  50. return -1;
  51. }
  52. do {
  53. //cout << fileInfo.name <<endl;
  54. strImageNameSets[iImageCount] = (string)fileInfo.name;
  55. iImageCount++;
  56. } while (_findnext(handle, &fileInfo) == 0);
  57. return iImageCount;
  58. }
  59. void encoding_gif(string strImgPath, string strGifName)
  60. {
  61. string strImgSets[100] = {};
  62. int iImgCount = TraverseFolder(strImgPath, strImgSets);
  63. string strTmp = strImgPath.substr(0, strImgPath.find_last_of("/") + 1);
  64. CxImage** img = new CxImage*[iImgCount];
  65. if (img == NULL) {
  66. cout << "new Cximage error!" << endl;
  67. return;
  68. }
  69. std::wstring stemp;
  70. LPCWSTR PicName;
  71. for (int i = 0; i < iImgCount; i++) {
  72. string tmp1;
  73. tmp1 = strTmp + strImgSets[i];
  74. stemp = s2ws(tmp1); // Temporary buffer is required
  75. PicName = stemp.c_str();
  76. img[i] = new CxImage;
  77. img[i]->Load(PicName, CXIMAGE_FORMAT_BMP);
  78. //bpp = 1;  bpp = 4;             bpp = 8;
  79. if (0 == img[i]->GetNumColors())
  80. {
  81. img[i]->DecreaseBpp(8, true);
  82. }
  83. }
  84. CxIOFile hFile;
  85. stemp = s2ws(strGifName); // Temporary buffer is required
  86. PicName = stemp.c_str();
  87. string Method = "wb";
  88. std::wstring  stempmd = s2ws(Method);
  89. LPCWSTR wMethod = stempmd.c_str();
  90. bool BFlag = hFile.Open(PicName, wMethod);
  91. CxImageGIF multiimage;
  92. multiimage.SetLoops(-1);
  93. multiimage.SetFrameDelay(300);
  94. multiimage.SetDisposalMethod(2);
  95. multiimage.Encode(&hFile, img, iImgCount, false, false);
  96. hFile.Close();
  97. delete[] img;
  98. }

main测试代码:

[cpp]  view plain  copy
  1. string strImgPath = "img/*.bmp";
  2. string strGifName = "img/test.gif";
  3. encoding_gif(strImgPath, strGifName);

测试结果是可以生成gif图片。再次表示感谢!

中途有个事情说下:在编译测试的过程中有个错误提示

cximage.lib(ximapsd.obj) : error LNK2001: 无法解析的外部符号 _psd_image_free 
cximage.lib(ximapsd.obj) : error LNK2019: 无法解析的外部符号 _psd_main_loop
解决方案:
libdcr.lib
libpsd.lib
将这两个包括进来就可以了。

三、CreateGIF

Csdn上资源:http://download.csdn.net/detail/iamshuke/2567835

非常感谢!若有问题,请随时联系。

本程序是用基于MFC的,对于我来使用,我不用MFC。

其中重要的文件,其他的都是调用过程:

主要函数贴下:

[html]  view plain  copy
  1. BOOL GetData(HBITMAP hBmp,BYTE **ppPalette,BYTE **ppData,BYTE *pBitsPixel,int *pWidth,int *pHeight);
  2. void CreateGIFHeard(CFile &file,WORD nImageWidth,WORD nImageHeight,BYTE bitsPixel);
  3. void AddImageToGIF(CFile &file,BYTE *pData,BYTE *palette,WORD nImageWidth,WORD nImageHeight,BYTE bitsPixel,WORD nDelay,
  4. short int nTransparentColorIndex);
  5. void CloseGIF(CFile &file);

C++生成GIF小结相关推荐

  1. 机器学习之判别/生成模型小结

    1. 简介 监督学习的任务就是学习一个模型,应用该模型对给定的输入预测相应的输出,这个模型的一般形式为决策函数:f(X)f(X)f(X). 或者条件概率分布:P(Y∣X)P(Y∣X)P(Y∣X). 监 ...

  2. 利用 freemarker 模板生成 word 小结

    在企业级开发时,不可避免的会遇到生成 word 文档的需求,有两种常用的方案,1.使用 Apache POI 在后台通过代码生成 word 文档:2.使用模板生成 word 文档.第二种方法比较简单, ...

  3. 全局唯一递增的id_全局唯一性ID生成方法小结

    全局ID通常要满足分片的一些要求: 1 不能有单点故障. 2 以时间为序,或者ID里包含时间.这样一是可以少一个索引,二是冷热数据容易分离. 3 可以控制ShardingId.比如某一个用户的文章要放 ...

  4. matlab生成随机数小结,MATLAB生成随机数总结

    1,rand 生成均匀分布的伪随机数.分布在(0~1)之间 语法:rand(m,n)生成m行n列的均匀分布的伪随机数 rand(m,n,'double')生成指定精度的均匀分布的伪随机数,参数还可以是 ...

  5. Java ASM框架与字节码插桩的常见用法(生成类,修改类,方法插桩,方法注入)

    前言 ASM 是一款读写Java字节码的工具,可以达到跳过源码编写,编译,直接以字节码的形式创建类,修改已经存在类(或者jar中的class)的属性,方法等. 通常用来开发一些Java开发的辅助框架, ...

  6. canvas贝塞尔曲线爱心_canvas实现高阶贝塞尔曲线(N阶贝塞尔曲线生成器)

    写在最前 由于原生的Canvas最高只支持到三阶贝塞尔曲线,那么我想添加多个控制点怎么办呢?(即便大部分复杂曲线都可以用3阶贝塞尔来模拟)与此同时,关于贝塞尔控制点的位置我们很难非常直观的清楚到底将控 ...

  7. 结对作业2:单元测试

    (201421123002 翁珊:201421123006 黄月梅:201421123007 徐晓珊) 题目要求: 结对编程实现上述功能,同样的,在程序正式开发之前,请先预估下PSP每个环节的消耗时间 ...

  8. java面向对象小知识

    (一).面向对象的由来: 1.60年中期软件危机(software crisis)--落后的软件生产方式无法满足迅速增长的计算机软件需求,从而导致软件开发与维护过程中出现的一系列严重问题的现象. 软禁 ...

  9. 【NLP】动手实现一个句子生成器

    本文主要介绍如何通过预先设定好的语法规则以及单词,通过Python来自动生成一些句子. 文章目录 解析语法 生成句子 小结 解析语法 在生成句子之前,我们需要先告诉机器生成句子的语法. 因此,我们先定 ...

最新文章

  1. selenium提取数据之driver对象的常用属性和方法
  2. linux tomcat端口冲突解决
  3. js 判断字符串是否包含某字符串
  4. VS2010和opencv2.4.9的配置
  5. [PAT乙级]1031 查验身份证
  6. JavaFX图表(三)之折线图
  7. 清华计算机系上热搜!近9成优秀毕业生放弃留学,前50名41人留校深造
  8. ajax 直接向后台发送请求,通过ajax异步向后端发送请求,响应请求向前端传送json格式数据的实现思路...
  9. Java基础入门笔记-布尔类型变量
  10. 1.2w 星!火爆 GitHub 的 Python 学习 100 天
  11. 用数字化数据战略取代数据“收集和管理”
  12. UVA434 Matty‘s Blocks【贪心】
  13. 为Autodesk Infrastructure Map Server(AIMS) Mobile Viewer创建自定义控件
  14. cadence allegro番外:制作flash焊盘
  15. 如何做社群运营才能提高用户的活跃度?
  16. Gateway网关简介以及使用
  17. DirextX9之2D编程 通过16位色位图创建背景透明的纹理
  18. 推特开发者账号的申请流程
  19. 基于FFMPEG水印添加---avfilter库
  20. Integration of image quality and motion cues for face anti-spoofing A neural network approach

热门文章

  1. alios things开发板_AliOS Things开发:让你的开发板支持AliOS Studio调试-阿里云开发者社区...
  2. 新起点,新希望,为梦想而战!!!
  3. Paper Reading||Differentiable Dynamic Quantization with Mixed Precision and Adaptive Resolution
  4. Phpspreadsheet 中文文档(六)读写文件+读取文件
  5. 《文明3》全攻略之设置篇
  6. 三维点图和三维PCA图
  7. fiddler手机下载证书提示No root certificate was found. Have you enabled HTTPS traff 解决方法 及手机配置代理后无网络问题
  8. 成功靠奋斗,奋斗靠坚持
  9. 2020-2021学年第二学期期末考试《药用高分子材料》大作业
  10. HDU——2546 饭卡