声明:所有权利保留。

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

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

一、GIF.h

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

Gif.h头文件代码如下:

使用方法如下:

//GifWriter m_gif_writer;
//char* file_name = "E:\\aaa.gif";
//int width = 128;
//int height = 128;
//int delay = 10;
//GifBegin(&m_gif_writer, file_name, width, height, delay);
// 代码里面自动从第一帧开始。只第一帧添加GIF的头信息
//for ()
//{
////GifWriteFrame()
//}
//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头文件:

#pragma once
#ifndef _MGIF_H__
#define _MGIF_H__ #include <string> using namespace std; void decoding_gif(string strGifName, string strSavePath);
void encoding_gif(string strImgPath, string strGifName); #endif //

mGif.CPP文件:

//Cartzhang
#include "mGif.h" #include "stdafx.h"
#include "mGif.h"
#include <iostream>
#include "ximagif.h"
#include <io.h> using namespace std; std::wstring s2ws(const std::string& s)
{
int len;
int slength = (int)s.length() + 1;
len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
wchar_t* buf = new wchar_t[len];
MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
std::wstring r(buf);
delete[] buf;
return r;
} void decoding_gif(string strGifName, string strSavePath)
{
CxImage img; std::wstring stemp = s2ws(strGifName); // Temporary buffer is required
LPCWSTR PicName = stemp.c_str();
img.Load(PicName, CXIMAGE_FORMAT_GIF); int iNumFrames = img.GetNumFrames();
cout << "frames num = " << iNumFrames << endl; CxImage* newImage = new CxImage(); for (int i = 0; i < iNumFrames; i++) {
newImage->SetFrame(i);
newImage->Load(PicName, CXIMAGE_FORMAT_GIF); char tmp[64];
sprintf(tmp, "%d", i); string tmp1;
tmp1 = tmp1.insert(0, tmp); tmp1 = strSavePath + tmp1 + ".png";
stemp = s2ws(tmp1); // Temporary buffer is required
PicName = stemp.c_str();
newImage->Save(PicName, CXIMAGE_FORMAT_PNG);
} if (newImage) delete newImage;
} int TraverseFolder(const string strFilePath, string strImageNameSets[])
{
int iImageCount = 0; _finddata_t fileInfo; long handle = _findfirst(strFilePath.c_str(), &fileInfo); if (handle == -1L) {
cerr << "failed to transfer files" << endl;
return -1;
} do {
//cout << fileInfo.name <<endl;
strImageNameSets[iImageCount] = (string)fileInfo.name; iImageCount++; } while (_findnext(handle, &fileInfo) == 0); return iImageCount;
} void encoding_gif(string strImgPath, string strGifName)
{
string strImgSets[100] = {}; int iImgCount = TraverseFolder(strImgPath, strImgSets); string strTmp = strImgPath.substr(0, strImgPath.find_last_of("/") + 1); CxImage** img = new CxImage*[iImgCount];
if (img == NULL) {
cout << "new Cximage error!" << endl;
return;
}
std::wstring stemp;
LPCWSTR PicName;
for (int i = 0; i < iImgCount; i++) {
string tmp1;
tmp1 = strTmp + strImgSets[i];
stemp = s2ws(tmp1); // Temporary buffer is required
PicName = stemp.c_str();
img[i] = new CxImage;
img[i]->Load(PicName, CXIMAGE_FORMAT_BMP);
//bpp = 1; bpp = 4; bpp = 8;
if (0 == img[i]->GetNumColors())
{
img[i]->DecreaseBpp(8, true);
}
} CxIOFile hFile;
stemp = s2ws(strGifName); // Temporary buffer is required
PicName = stemp.c_str(); string Method = "wb";
std::wstring stempmd = s2ws(Method);
LPCWSTR wMethod = stempmd.c_str();
bool BFlag = hFile.Open(PicName, wMethod); CxImageGIF multiimage; multiimage.SetLoops(-1);
multiimage.SetFrameDelay(300);
multiimage.SetDisposalMethod(2);
multiimage.Encode(&hFile, img, iImgCount, false, false); hFile.Close(); delete[] img;
}

main测试代码:

	string strImgPath = "img/*.bmp";

	string strGifName = "img/test.gif";
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。

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

主要函数贴下:

BOOL GetData(HBITMAP hBmp,BYTE **ppPalette,BYTE **ppData,BYTE *pBitsPixel,int *pWidth,int *pHeight);

void CreateGIFHeard(CFile &file,WORD nImageWidth,WORD nImageHeight,BYTE bitsPixel);

void AddImageToGIF(CFile &file,BYTE *pData,BYTE *palette,WORD nImageWidth,WORD nImageHeight,BYTE bitsPixel,WORD nDelay,
short int nTransparentColorIndex); void CloseGIF(CFile &file);

--------------------------------------

若有问题,请随时联系!

非常感谢各位!

C++生成GIF小结的更多相关文章

  1. VS2017中 C# dll引用(C生成dll,C++生成dll)小结 - 简书

    原文:VS2017中 C# dll引用(C生成dll,C++生成dll)小结 - 简书 dll引用小结 一.dll与应用程序 动态链接库(也称为DLL,即为“Dynamic Link Library” ...

  2. 全局唯一性ID生成方法小结

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

  3. (引用)Python 生成随机数小结

    转载:http://blog.csdn.net/shuaijiasanshao/article/details/51339438

  4. Oracle分区索引

    索引与表类似,也可以分区: 分区索引分为两类: Locally partitioned index(局部分区索引) Globally partitioned index(全局分区索引) 下面就来详细解 ...

  5. CUDA 程序中的同步

    前言 在并发,多线程环境下,同步是一个很重要的环节.同步即是指进程/线程之间的执行顺序约定. 本文将介绍如何通过共享内存机制实现块内多线程之间的同步. 至于块之间的同步,需要使用到 global me ...

  6. 使用 CUBLAS 库给矩阵运算提速

    前言 编写 CUDA 程序真心不是个简单的事儿,调试也不方便,很费时.那么有没有一些现成的 CUDA 库来调用呢? 答案是有的,如 CUBLAS 就是 CUDA 专门用来解决线性代数运算的库. 本文将 ...

  7. CUDA 标准编程模式

    前言 本文将介绍 CUDA 编程的基本模式,所有 CUDA 程序都基于此模式编写,即使是调用库,库的底层也是这个模式实现的. 模式描述 1. 定义需要在 device 端执行的核函数.( 函数声明前加 ...

  8. Cublas矩阵加速运算

    前言 编写 CUDA 程序真心不是个简单的事儿,调试也不方便,很费时.那么有没有一些现成的 CUDA 库来调用呢? 答案是有的,如 CUBLAS 就是 CUDA 专门用来解决线性代数运算的库. 本文将 ...

  9. .NET Core开发日志——Entity Framework与PostgreSQL

    Entity Framework在.NET Core中被命名为Entity Framework Core.虽然一般会用于对SQL Server数据库进行数据操作,但其实它还支持其它数据库,这里就以Po ...

随机推荐

  1. 使用Spring框架的好处

    转自:https://www.cnblogs.com/hoobey/p/6032506.html 在SSH框假中spring充当了管理容器的角色.我们都知道Hibernate用来做持久层,因为它将JD ...

  2. css实现简单的告警提示动画效果

    需求:css实现简单的告警提示动画效果,当接收到实时信息的时候,页面弹出告警信息的动画效果 <!DOCTYPE html> <html lang="en"> ...

  3. 项目太大tomcat启动不起来

    双击server,Open launch configuration Arguments VM arguments增加参数: -Xms512m -Xmx1024m -Xss4m -XX:PermSiz ...

  4. 【软件project】 文档 - 银行业务管理 - 需求分析

    ---------------------------------------------------------------------------------------------------- ...

  5. 什么是MVC,什么是WCF

    在C#中总会遇到这几个概念,网上搜了一下,做一下总结和比较,东拼西凑,如有雷同,纯属直接拷贝,人懒,但无意侵权. 1.什么是MVC MVC是三个单词的首字母缩写,它们是Model(模型).View(视 ...

  6. POJ 3723 Conscription MST

    http://poj.org/problem?id=3723 题目大意: 需要征募女兵N人,男兵M人,没征募一个人需要花费10000美元,但是如果已经征募的人中有一些关系亲密的人,那么可以少花一些钱, ...

  7. 这一篇sigmoid和softmax的比较,讲的不错

    文章: http://blog.csdn.net/u014422406/article/details/52805924 sigmoid函数(也叫逻辑斯谛函数):  引用wiki百科的定义: A lo ...

  8. 具体解释ebs接口之客户配置文件导入(二)

    ------------------------------------ -- 1a. Setup the Org_id ------------------------------------ ex ...

  9. 开发板 视频1 05_01 05_02 05_03 关于ubuntu的一些操作

    ctrl+alt+T 打开中端 ctrl+d  退出 ctrl+alt+f1 到f6 进入dos中端 ctrl+alt+f7 是退出 05_02 启动root用户   也就是进入 前面出现root了 ...

  10. 【POJ 1226】Substrings

    [链接]h在这里写链接 [题意] 给你n个字符串. 让你找一个字符串s. 设s'为这个字符串的逆序. 要求s或者s'在每个字符串里都能够找得到. 并且要求s的长度最长. 求出这个最长的串的长度. [题 ...