GDI+ gif文件的显示和格式转换
GDI+ gif文件的显示和格式转换
怎么获取gif文件的每一帧,并且显示出来呢?
1.怎么用gid+显示gif文件
总体思路:用Image装载图像,用Graphic显示图像。
相关函数:
(1)Image::FromFile可以从文件中加载一个图像。
可以加载的文件类型有: BMP, GIF, JPEG, PNG, TIFF, and EMF
Image* image = Image::FromFile(_T("res//test.gif"));
(2)Image::GetFrameDimensionsCount 返回一个所谓的“维度”的个数,
每个维 度可能包含多个帧,gif文件就是包含1个维度,然后维度中可能包含
不定数目的帧。
UINT count = image->GetFrameDimensionsCount();
(3)Image::GetFrameDimensionsList 就是获得这些维度的GUID列表。
先分配count个GUID的数组。
GUID *pDimensionIDs=(GUID*)new GUID[count];
image->GetFrameDimensionsList(pDimensionIDs, count);
(4)Image::GetFrameCount获得指定的“维数”有多少帧。
UINT FrameNums=image->GetFrameCount(&pDimensionIDs[0]);
(5) 获得每帧之间的时间间隔。
PropertyTagFrameDelay是GDI+中预定义的一个GIG属性ID值,表示标
签帧数据的延迟时间。
先调用 Image::GetPropertyItemSize获得有多少个时间间隔属性item.
然后调用Image::GetPropertyItem填充获得的items.
UINT FrameDelayNums=image->GetPropertyItemSize
(PropertyTagFrameDelay);
PropertyItem * lpPropertyItem=new PropertyItem
[FrameDelayNums];
image->GetPropertyItem
(PropertyTagFrameDelay,FrameDelayNums,lpPropertyItem);
时间间隔就保存在PropertyItem的value成员中。
(6)最后,用一个while循环来循环显示每一帧。
Image::SetActiveFrame来设置显示那一帧。
总体的代码如下:
- //装载gif文件
- Image* image = Image::FromFile(_T("res//test.gif"));
- //获得有多少个维度,对于gif就一个维度
- UINT count = image->GetFrameDimensionsCount();
- GUID *pDimensionIDs=(GUID*)new GUID[count];
- image->GetFrameDimensionsList(pDimensionIDs, count);
- TCHAR strGuid[39];
- StringFromGUID2(pDimensionIDs[0], strGuid, 39);
- UINT frameCount=image->GetFrameCount(&pDimensionIDs[0]);
- delete []pDimensionIDs;
- //获得这个维度有多少个帧
- UINT FrameNums=image->GetFrameCount(&pDimensionIDs[0]);
- //获得各帧之间的时间间隔
- //先获得有多少个时间间隔,PropertyTagFrameDelay是GDI+中预定义的一个GIG属性ID值,表示标签帧数据的延迟时间
- UINT FrameDelayNums=image->GetPropertyItemSize(PropertyTagFrameDelay);
- PropertyItem * lpPropertyItem=new PropertyItem[FrameDelayNums];
- image->GetPropertyItem(PropertyTagFrameDelay,FrameDelayNums,lpPropertyItem);
- //Guid的值在显示GIF为FrameDimensionTime,显示TIF时为FrameDimensionPage
- int FrameCount=0;
- GUID Guid = FrameDimensionTime;
- image->SelectActiveFrame(&Guid,FrameCount);
- while(true)
- {
- Graphics gh(pDC->GetSafeHdc());
- //显示当前帧
- gh.DrawImage(image,0,0,image->GetWidth(),image->GetHeight());
- //时间间隔
- long lPause = ((long*)lpPropertyItem->value)[FrameCount]*10;
- Sleep(lPause);
- //设置当前需要显示的帧数
- if ((FrameCount+1)==FrameNums)
- { //如果已经显示到最后一帧,那么重新开始显示
- FrameCount=0;
- image->SelectActiveFrame(&Guid,0);
- }
- else
- {
- image->SelectActiveFrame(&Guid,++FrameCount);
- }
- }
2.怎么将gif中的某一帧提取出来,保存为其他的文件格式。
(1) Image::Save函数
Status Save( const WCHAR *filename,
const CLSID *clsidEncoder,
const EncoderParameters *encoderParams
);
其中第一个参数是表示要保存的文件名称,第二个参数是想采用的编码器,不同
的图片格式对应的编码器也不一样。第三个参数设为NULL即可。
(2)要得到参数2,必须调用函数:
Image::GetImageEncodersSize来获得编码器列表
Image::GetImageEncoders来获得对应的编码器相关信息(包括CLSID)
下面是相关的代码:
- //获得指定格式的编码器的CLSID
- int CTestGifImageDlg::GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
- {
- UINT num = 0; // number of image encoders
- UINT size = 0; // size of the image encoder array in bytes
- ImageCodecInfo* pImageCodecInfo = NULL;
- GetImageEncodersSize(&num, &size);
- if(size == 0)
- return -1; // Failure
- pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
- if(pImageCodecInfo == NULL)
- return -1; // Failure
- GetImageEncoders(num, size, pImageCodecInfo);
- for(UINT j = 0; j < num; ++j)
- {
- if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
- {
- *pClsid = pImageCodecInfo[j].Clsid;
- free(pImageCodecInfo);
- return j; // Success
- }
- }
- free(pImageCodecInfo);
- return -1; // Failure
- }
- bool CTestGifImageDlg::DrawGifFrame(CDC * pDC)
- {
- //装载gif文件
- Image* image = Image::FromFile(_T("res//test.gif"));
- //获得有多少个维度,对于gif就一个维度
- UINT count = image->GetFrameDimensionsCount();
- GUID *pDimensionIDs=(GUID*)new GUID[count];
- image->GetFrameDimensionsList(pDimensionIDs, count);
- TCHAR strGuid[39];
- StringFromGUID2(pDimensionIDs[0], strGuid, 39);
- UINT frameCount=image->GetFrameCount(&pDimensionIDs[0]);
- delete []pDimensionIDs;
- //获得这个维度有多少个帧
- UINT FrameNums=image->GetFrameCount(&pDimensionIDs[0]);
- //将第一帧转换为png图片保存
- GUID Guid = FrameDimensionTime;
- image->SelectActiveFrame(&Guid,0);
- //保存
- CLSID encoderClsid;
- if(GetEncoderClsid(_T("image/png"), &encoderClsid) >= 0)
- {
- image->Save(_T("pngfiles//test.png"),&encoderClsid,NULL);
- }
- }
GDI+ gif文件的显示和格式转换的更多相关文章
- MATLAB 文件对话框之图片格式转换
localpathname为当前路径,需要保存图片的位置,根据自己的实际路径设置,usedpathname用来保存打开的文件位置,方便下次打开文件对话框以上次的路径为默认路径. global used ...
- Android 读取txt文件并以utf-8格式转换成字符串
博客: 安卓之家 微博: 追风917 CSDN: 蒋朋的家 简书: 追风917 博客园: 追风917 # 使用EncodingUtils 今天用到了城市选择三级联动的库,用的这个:https://gi ...
- 关于MySQL中使用LOAD DATA INFILE导入csv文件时的日期格式问题
在使用MySQL时,常常会用到Load Data Infile来导入数据,在遇到Date类型的列时,有时会遇到格式转换的问题: 首先创建一张简单的people表,包含名字,生日,年龄三个字段: mys ...
- 批量操作文本文件进行dos/unix格式转换
批量将目录下所有文件进行 dos/unix 格式转换 使用 sed + grep #sed -i "s/原字符串/新字符串/g" `grep 原字符串 -rl 所在目录` eg: ...
- 【VC++技术杂谈007】使用GDI+进行图片格式转换
本文主要介绍如何使用GDI+对图片进行格式转换,可以转换的图片格式为bmp.jpg.png. 1.加载GDI+库 GDI+是GDI图形库的一个增强版本,提供了一系列Visual C++ API.为了使 ...
- day21 TFRecord格式转换MNIST并显示
首先简要介绍了下TFRecord格式以及内部实现protobuf协议,然后基于TFRecord格式,对MNIST数据集转换成TFRecord格式,写入本地磁盘文件,再从磁盘文件读取,通过pyplot模 ...
- Python3 将configparser从ini文件中读取的内容转换成字典格式
因为写脚本的用到了,所以研究了下怎么将configparser从ini文件中读取的内容转换成字典格式. 整理一下,希望能对大家有帮助. 从http://stackoverflow.com/questi ...
- convert 批量文件的格式转换
1.将 a.gif 转为 png 格式 convert a.gif a.png 请注意,convert 命令的基本格式为 convert 源文件 [参数] 目标文件 在上面的命令中,源文件是 a.gi ...
- 腾讯视频QLV格式转换mp4的方法
腾讯视频QLV格式转换mp4的方法不知道大家知不知道用?喜欢用腾讯视频的朋友应该都知道腾讯视频单独搞出了个QLV格式文件,只能用腾讯独有的腾讯视频软件才能播放,就算用格式工厂转换也不行,那么腾讯视频的 ...
随机推荐
- c++ 文件增加#ifndef、#define 和 #endif 语句的意义
文件currency.h (或 currencyOverload.h) 包含了 currency类的声明和实现细节. 在文件头, 应该加上语句 #ifndef Currency_ #define Cu ...
- python爬虫数据-下载图片经典案例
'''Urllib 模块提供了读取web页面数据的接口,我们可以像读取本地文件一样读取www和ftp上的数据.首先,我们定义了一个getHtml()函数: urllib.urlopen()方法用于打开 ...
- Java如何中断正在运行的线程?
在Java编程中,如何中断正在运行的线程? 以下示例演示如何使用Thread类的interrupt()方法中断正在运行线程,并检查线程是否使用isInterrupted()方法中断. package ...
- e839. 使JTabbedPane中的卡片可滚动
By default, all the tabs in a tabbed pane are displayed. When the tabs are wider than the width of t ...
- C#或者.NET下的强制垃圾回收办法
转载 2011年03月16日 17:21:00 标签: c# / .net / button / object / stream / class 8185 今天来谈谈C#的GC,也就是垃圾回收机制,非 ...
- 嵌入式开发之zynq驱动—— zynq ps pl ddr 内存地址空间映射
http://www.wiki.xilinx.com/Zynq-7000+AP+SoC+-+32+Bit+DDR+Access+with+ECC+Tech+Tip http://patchwork.o ...
- svn -- svn安装与配置
1.SVN分为服务器端与客户端 l 服务器端:VisualSVN SubVersion l 客户端:TortoiseSVN server http://www.visualsvn.com/ cli ...
- eclipse 访问 hive1.2.1
参考链接1.http://www.iteblog.com/archives/846 操作实际参考代码:http://sunhs.sinaapp.com/?p=343 配置eclipse 搞1天, 不管 ...
- winform 实现选择文件和选择文件夹对话框
//选择文件,点击[浏览],选择文件 private void button1_Click(object sender, EventArgs e) { OpenFileDialog openFileD ...
- [转]十个 iOS 面试问题
原文地址:http://onevcat.com/2013/04/ios-interview/ 不管对于招聘和应聘来说,面试都是很重要的一个环节,特别对于开发者来说,面试中的技术问题环节不仅是企业对应聘 ...