C++生成GIF小结

 声明:所有权利保留。

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


近来需要把BMPKinect的内存图片多张合成为小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位版本,所以使用了x64release模式。有个与mfc相关的编译不过,直接无视了,本人用不上mfc

生成的为lib的静态库。

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

 


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

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

其实主要是处理相关文件夹方便来调用的。非常感谢网友提供,头文件和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);

 

 

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

若有问题,请随时联系!

非常感谢各位!  

 

 

已标记关键词 清除标记
相关推荐
程序员的必经之路! 【限时优惠】 现在下单,还享四重好礼: 1、教学课件免费下载 2、课程案例代码免费下载 3、专属VIP学员群免费答疑 4、下单还送800元编程大礼包 【超实用课程内容】  根据《2019-2020年中国开发者调查报告》显示,超83%的开发者都在使用MySQL数据库。使用量大同时,掌握MySQL早已是运维、DBA的必备技能,甚至部分IT开发岗位也要求对数据库使用和原理有深入的了解和掌握。 学习编程,你可能会犹豫选择 C++ 还是 Java;入门数据科学,你可能会纠结于选择 Python 还是 R;但无论如何, MySQL 都是 IT 从业人员不可或缺的技能!   套餐中一共包含2门MySQL数据库必学的核心课程(共98课时)   课程1:《MySQL数据库从入门到实战应用》   课程2:《高性能MySQL实战课》   【哪些人适合学习这门课程?】  1)平时只接触了语言基础,并未学习任何数据库知识的人;  2)对MySQL掌握程度薄弱的人,课程可以让你更好发挥MySQL最佳性能; 3)想修炼更好的MySQL内功,工作中遇到高并发场景可以游刃有余; 4)被面试官打破沙锅问到底的问题问到怀疑人生的应聘者。 【课程主要讲哪些内容?】 课程一:《MySQL数据库从入门到实战应用》 主要从基础篇,SQL语言篇、MySQL进阶篇三个角度展开讲解,帮助大家更加高效的管理MySQL数据库。 课程二:《高性能MySQL实战课》主要从高可用篇、MySQL8.0新特性篇,性能优化篇,面试篇四个角度展开讲解,帮助大家发挥MySQL的最佳性能的优化方法,掌握如何处理海量业务数据和高并发请求 【你能收获到什么?】  1.基础再提高,针对MySQL核心知识点学透,用对; 2.能力再提高,日常工作中的代码换新貌,不怕问题; 3.面试再加分,巴不得面试官打破沙锅问到底,竞争力MAX。 【课程如何观看?】  1、登录CSDN学院 APP 在我的课程中进行学习; 2、移动端:CSDN 学院APP(注意不是CSDN APP哦)  本课程为录播课,课程永久有效观看时长 【资料开放】 课件、课程案例代码完全开放给你,你可以根据所学知识,自行修改、优化。  下载方式:电脑登录课程观看页面,点击右侧课件,可进行课程资料的打包下载。
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页