声明:所有权利保留。

转载必须说明出处: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. [D3] Draw a basic US d3-geo map

    Install: npm install --save d3 d3-geo topojson Code: import React, {Component} from 'react'; import ...

  2. 原生js大总结十

    91.ajax的优点     a.提高运行效率   b.提高用户体验,让多件事情同时发生   c.在不刷新页面的情况下可以对局部数据进行加载和刷新       92.ajax请求的流程   1.创建通 ...

  3. maven的pom.xml配置文件讲解

    <project xmlns="http://maven.apache.org/POM/4.0.0 "     xmlns:xsi="http://www.w3.o ...

  4. 把java程序打包成.exe

    准备工作:将可执行的jar包跟资源跟第三方包都放到一个目录下. 能够将jre包也放入里面.这样在没有安装jre的情况下也能够执行. watermark/2/text/aHR0cDovL2Jsb2cuY ...

  5. Ext常用控件

    多选下拉框 var workname = new Ext.form.MultiSelect({ store: pointComboBoxStore, fieldLabel: '工作面', labelS ...

  6. 异步FIFO设计

    参考http://www.cnblogs.com/BitArt/archive/2013/04/10/3010073.html http://blog.sina.com.cn/s/blog_6d30f ...

  7. Apache的.htaccess项目根文件夹伪静态设置规则

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/ ...

  8. amazeui页面分析2

    amazeui页面分析2 一.总结 1.弄清结构:这些部分都是一块一块分好了的,掌握结构之后,想替换哪块就替换哪块,想不要哪块就不要哪块,非常简单的 2.一块一块:替换十分简单 3.弄清楚大块之后,然 ...

  9. PL/SQL笔记(一)

    PL/SQL概述 PL/SQL是一种高级的数据库程序设计语言,专门使用与Oracle语言基于数据库的服务器的内部,所以PL/SQL代码可以对数据库进行快速的处理. 1.什么是PL/SQL? PL/SQ ...

  10. Linux下的lds链接脚本简介(四)

    十一. 表达式 lds中表达式的文法与C语言的表达式文法一致,表达式的值都是整型,如果ld的运行主机和生成文件的目标机都是32位,则表达式是32位数据,否则是64位数据. 以下是一些常用的表达式: _ ...