声明:所有权利保留。

转载必须说明出处: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. 题目1205:N阶楼梯上楼问题(2008年华中科技大学计算机保研机试真题:递推求解)

    题目1205:N阶楼梯上楼问题 时间限制:1 秒 内存限制:128 兆 特殊判题:否 提交:2447 解决:927 题目描写叙述: N阶楼梯上楼问题:一次能够走两阶或一阶,问有多少种上楼方式. (要求 ...

  2. Windows Server 2016 上配置 APACHE+SSL+PHP+perl

    Windows Server 2016 上配置 APACHE+SSL+PHP+perl 安装环境 谷歌云实例 Windows Server 2016 Apache Apache/2.4.25 (win ...

  3. 2. Dubbo和Zookeeper的关系

    转自:https://www.cnblogs.com/hirampeng/p/9540243.html Dubbo建议使用Zookeeper作为服务的注册中心. 1.   Zookeeper的作用: ...

  4. Windows Forms 窗体篇

    1,显示窗体 非模式: Form form = new Form(); form.Show(); 模式: Form form = new Form(); form.Show(); 2,拥有者窗体与附属 ...

  5. canvas画板基础应用的学习

    canvas是html5中的绘图容器,我们可以通过javascript的控制来进行图形的绘制,绘制对象可以是路径.盒.圆.字符等,同时,你也可以通过js给画布添加图像,下面来介绍canvas的各种基本 ...

  6. JS概述

             从Asp.NET跨越到JavaScript.这既是一个新的领域也是一个非常熟悉的地方,新是由于不知道什么是JavaScript,首先来了解一下什么是JavaScript.       ...

  7. 【几何/数学】概念的理解 —— (非)刚体变换((non-)rigid transformation)

    1. 刚体变换与非刚体变换 What is a non-rigid transformation? 刚体变换(rigid transformation)一般分为如下几种: 平移对象,而不改变形状和大小 ...

  8. Android Gradle统一依赖管理

    目的: 避免在依赖包出新版本时,需要对每个module中的build.gradle文件都进行修改(如appcompat-v7包),使用这种方式即只需一次修改. 方法一 在项目的根目录创建一个gradl ...

  9. Undo表空间数据文件损坏

       UNDO表空间数据文件和system表空间数据文件都是数据库的关键数据文件,如果损坏会导致sql执行失败,用户无法登录,甚至实例崩溃等.同样恢复UNDO表空间数据文件也必须在数据库mount状态 ...

  10. Python代码优化及技巧笔记(一)

    前言 这里是记录一些本人在开发过程中遇到的一些细节问题.与君共勉. 版权说明 著作权归作者全部.商业转载请联系作者获得授权,非商业转载请注明出处. 作者:Coding-Naga链接:http://bl ...