C++生成GIF小结
声明:所有权利保留。
转载必须说明出处: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图片。再次表示感谢!
中途有个事情说下:在编译测试的过程中有个错误提示
libdcr.liblibpsd.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小结的更多相关文章
- VS2017中 C# dll引用(C生成dll,C++生成dll)小结 - 简书
原文:VS2017中 C# dll引用(C生成dll,C++生成dll)小结 - 简书 dll引用小结 一.dll与应用程序 动态链接库(也称为DLL,即为“Dynamic Link Library” ...
- 全局唯一性ID生成方法小结
全局ID通常要满足分片的一些要求:1 不能有单点故障.2 以时间为序,或者ID里包含时间.这样一是可以少一个索引,二是冷热数据容易分离.3 可以控制ShardingId.比如某一个用户的文章要放在同一 ...
- (引用)Python 生成随机数小结
转载:http://blog.csdn.net/shuaijiasanshao/article/details/51339438
- Oracle分区索引
索引与表类似,也可以分区: 分区索引分为两类: Locally partitioned index(局部分区索引) Globally partitioned index(全局分区索引) 下面就来详细解 ...
- CUDA 程序中的同步
前言 在并发,多线程环境下,同步是一个很重要的环节.同步即是指进程/线程之间的执行顺序约定. 本文将介绍如何通过共享内存机制实现块内多线程之间的同步. 至于块之间的同步,需要使用到 global me ...
- 使用 CUBLAS 库给矩阵运算提速
前言 编写 CUDA 程序真心不是个简单的事儿,调试也不方便,很费时.那么有没有一些现成的 CUDA 库来调用呢? 答案是有的,如 CUBLAS 就是 CUDA 专门用来解决线性代数运算的库. 本文将 ...
- CUDA 标准编程模式
前言 本文将介绍 CUDA 编程的基本模式,所有 CUDA 程序都基于此模式编写,即使是调用库,库的底层也是这个模式实现的. 模式描述 1. 定义需要在 device 端执行的核函数.( 函数声明前加 ...
- Cublas矩阵加速运算
前言 编写 CUDA 程序真心不是个简单的事儿,调试也不方便,很费时.那么有没有一些现成的 CUDA 库来调用呢? 答案是有的,如 CUBLAS 就是 CUDA 专门用来解决线性代数运算的库. 本文将 ...
- .NET Core开发日志——Entity Framework与PostgreSQL
Entity Framework在.NET Core中被命名为Entity Framework Core.虽然一般会用于对SQL Server数据库进行数据操作,但其实它还支持其它数据库,这里就以Po ...
随机推荐
- RMAN DUPLICATE ADG DEMO
RMAN DUPLICATE ADG DEMO 生产环境谨慎使用,建议生产环境采用RMAN备份恢复的方式. 本演示案例所用环境: primary standby OS Hostname pry s ...
- 00103_死锁、Lock接口、等待唤醒机制
1.死锁 (1)同步锁使用的弊端:当线程任务中出现了多个同步(多个锁)时,如果同步中嵌套了其他的同步.这时容易引发一种现象:程序出现无限等待,这种现象我们称为死锁.这种情况能避免就避免掉: synch ...
- 使用 LaTeX 绘制 PGM(Probabilistic Graphical Models)中的贝叶斯网络(bayesian networks)
Software for drawing bayesian networks (graphical models) 这里需要调用 latex 中的绘图库:TikZ and PGF. 注意,下述 tex ...
- 电脑c盘清理
https://www.cnblogs.com/btchenguang/archive/2012/01/20/2328320.html
- 【MemSQL Start[c]UP 3.0 - Round 1 A】 Declined Finalists
[链接]h在这里写链接 [题意] 在这里写题意 [题解] max(最大值-25,0) [错的次数] 0 [反思] 在这了写反思 [代码] #include <bits/stdc++.h> ...
- 【剑指offer】对面和相等的正方体
转载请注明出处:http://blog.csdn.net/ns_code/article/details/26509459 剑指offer上的全排列相关题目. 输入一个含有8个数字的数组.推断有么有可 ...
- spark1.3.1使用基础教程 分类: B8_SPARK 2015-04-28 11:10 1651人阅读 评论(0) 收藏
spark可以通过交互式命令行及编程两种方式来进行调用: 前者支持scala与python 后者支持scala.python与java 本文参考https://spark.apache.org/d ...
- Qt没有被正确安装,请运行make install问题的解决
在网上直接下载别人编译好的Qt库,为自己使用省了不少事.但往往也会遇到些问题,其中Qt version is not properly installed,please run make instal ...
- Giraph源代码分析(六)——Edge 分析
HamaWhite 原创,转载请注明出处.欢迎大家增加Giraph 技术交流群: 228591158 欢迎訪问: 西北工业大学 - 大数据与知识管理研究室 (Northwestern Polytech ...
- php替换空格(php函数的设计思路)
php替换空格(php函数的设计思路) 一.总结 1.替换和也是先查找了再替换,截取的话就是先查找到再截取 2.设计函数的时候按照的是缺省参数在后,核心东西在前的思路来设计函数的:查找的话是$sear ...