【转载】使用Imaging组件加载GIF动画
Mobil手机加载GIF动态图像的方法有两种,一个就是使用GIF89a标准算法,另一个就是使用SDK自带的Imaging组件,这两种方法是很典型的手机图像处理技术的实践。使用Imaging组件加载GIF比使用标准算法处理高效的多,特别是在处理真彩GIF动画表现更加突出。
Imaging组件中封装了对大部分图片格式的编解码算法,并以接口的形式提供给开发人员使用。Imaging组件是GDI+的微缩版。但是在实际使用上又有很大的不同。使用Imaging组件来加载GIF动态图片调用了几乎所有的Imaging接口,看看我们将要用到的接口:
IImagingFactory:图像操作最初要用到的接口,它的接口方法全是带CreateXXX的函数,可见他的制造工厂的特性。使用前需要调用CoCreateInstance初始化。
IImageDecoder:主要的图像操作接口,用来处理从大部分图像格式中获取数据。
IbitmapImage:主要的图位操作接口,这里能够对具体的图像像素进行运算。
IImage:主要的图形控制接口,也许是Imaging组件唯一的绘制接口
IImageSink:这个东东似乎是一个过渡性质的接口,它的亮点在它的sink的动词解释上:沉!
操作:
首先我们要使用IImagingFactory的CreateImageDecoderppy初始化IimageDecoder。使用这个方法取得GIF图像数据,用IimagingFactory的CreateNewBitmap初始化IbitmapImage。通过这个接口执行QueryInterface取得IImage和IimageSink,然后调用IimageDecoder的SelectActiveFrame设定当前的图像块数据。此时对获得的IimageSink进行decode,decode完毕后调用Iimage接口的draw方法,此时画出的就是指定的那个图像块图像。
部分代码:
文件到流的转化
![](/assets/blank.gif)
![](/assets/blank.gif)
1 HRESULT CGIFImage::CreateStreamOnFile(const TCHAR * tszFilename, IStream ** ppStream)
2
3 {
4
5 HRESULT hrRet = S_OK;
6
7 HGLOBAL hg = NULL;
8
9 HANDLE hGIFFile = NULL;
10
11 DWORD dwSize, dwRead;
12
13 BYTE* pbLocked = NULL;
14
15
16
17 // 建立一个文件池,我管CreateFile返回的handle这个叫文件池
18
19 hGIFFile = CreateFile(tszFilename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
20
21 //当handle地址为-1时表示没有创建成功
22
23 if (INVALID_HANDLE_VALUE == hGIFFile)
24
25 {
26
27 hrRet = E_PENDING + GetLastError();
28
29 goto error;
30
31 }
32
33 dwSize = GetFileSize(hGIFFile, NULL);
34
35 //当尺寸溢出时放弃
36
37 if (INVALID_FILE_SIZE == dwSize)
38
39 {
40
41 hrRet = E_PENDING + GetLastError();
42
43 goto error;
44
45 }
46
47
48
49 // 分配一个文件尺寸相同的活动内存池
50
51 hg = GlobalAlloc(GMEM_MOVEABLE, dwSize);
52
53 //分配失败即放弃
54
55 if (NULL == hg)
56
57 {
58
59 hrRet = E_PENDING + GetLastError();
60
61 goto error;
62
63 }
64
65
66
67 //使用GlobalLock得到内存指针
68
69 pbLocked = (BYTE*) GlobalLock(hg);
70
71 //lock失败放弃
72
73 if (NULL == pbLocked)
74
75 {
76
77 hrRet = E_PENDING + GetLastError();
78
79 goto error;
80
81 }
82
83
84
85 // copy the file
86
87 if (!ReadFile(hGIFFile, pbLocked, dwSize, &dwRead, NULL))
88
89 {
90
91 hrRet = E_PENDING + GetLastError();
92
93 goto error;
94
95 }
96
97
98
99 GlobalUnlock(hg);
100
101
102
103 // 创建文件流
104
105 hrRet = CreateStreamOnHGlobal(hg, TRUE, ppStream);
106
107
108
109 CloseHandle(hGIFFile);
110
111 return hrRet;
112
113 error:
114
115 if (pbLocked)
116
117 GlobalUnlock(hg);
118
119 if (hg)
120
121 GlobalFree(hg);
122
123 if (hGIFFile)
124
125 CloseHandle(hGIFFile);
126
127 return hrRet;
128
129
130
131
文件加载
Code
在定时器中执行下面代码,不仅实现了GIF动画的播放,还支持透明GIF动画的播放
Draw(HDC hDC,HWND hWnd,int XDest,int YDest)方法
![](/assets/blank.gif)
![](/assets/blank.gif)
1 if(m_GIFImageDecoder==0)
2
3 {
4
5 return 0;
6
7 }
8
9 //选择某个维面上的某一贞做为当前的活动贞
10
11 m_GIFImageDecoder->SelectActiveFrame(&m_pdi,m_nCurPage);
12
13 m_GIFImageDecoder->BeginDecode(m_GIFImageSink,NULL);
14
15 /*while (E_PENDING == (m_GIFImageDecoder->Decode()))
16
17 {
18
19 Sleep(10);
20
21 }*/
22
23 m_GIFImageDecoder->Decode();
24
25 m_GIFImageDecoder->EndDecode(E_FAIL);
26
27
28 RECT rt;
29
30 rt.left=XDest;
31
32 rt.top=YDest;
33
34 rt.right=XDest+m_iif.Width;
35
36 rt.bottom=YDest+m_iif.Height;
37
38
39 HDC hdcMemory=CreateCompatibleDC(hDC);
40
41 HBITMAP hBitmapMemory=CreateCompatibleBitmap(hDC,m_iif.Width,m_iif.Height);
42
43 HBITMAP hOldBitmapMemory=(HBITMAP)SelectObject(hdcMemory,hBitmapMemory);
44
45
46
47 HDC hdcbkMemory=CreateCompatibleDC(hDC);
48
49 HBITMAP hBitmapbkMemory=CreateCompatibleBitmap(hDC,m_iif.Width,m_iif.Height);
50
51 HBITMAP hOldbkBitmap=(HBITMAP)SelectObject(hdcbkMemory,hBitmapbkMemory);
52
53 if(NULL==m_hBKBitmap)
54
55 {
56
57 BitBlt(hdcbkMemory,0,0,m_iif.Width,m_iif.Height,hDC,rt.left,rt.top,SRCCOPY);
58
59 m_hBKBitmap=(HBITMAP)SelectObject(hdcbkMemory,hOldbkBitmap);
60
61 }
62
63 SelectObject(hdcbkMemory,m_hBKBitmap);
64
65 BitBlt(hdcMemory,0,0,m_iif.Width,m_iif.Height,hdcbkMemory,0,0,SRCCOPY);
66
67 //SelectObject(hdcbkMemory,hOldbkBitmap);
68
69 DeleteObject(hOldbkBitmap);
70
71 DeleteObject(hBitmapbkMemory);
72
73 DeleteDC(hdcbkMemory);
74
75 hdcbkMemory=NULL;
76
77 hOldbkBitmap=NULL;
78
79 hBitmapbkMemory=NULL;
80
81
82 m_GIFImage->Draw(hdcMemory,CRect(0,0,m_iif.Width,m_iif.Height),NULL);
83
84 BitBlt(hDC,rt.left,rt.top,m_iif.Width,m_iif.Height,hdcMemory,0,0,SRCCOPY);
85
86 SelectObject(hdcMemory,hOldBitmapMemory);
87
88 DeleteObject(hBitmapMemory);
89
90 DeleteObject(hOldBitmapMemory);
91
92 //DeleteObject(hBitmapbkMemory);
93
94 hBitmapMemory=NULL;
95
96 hOldBitmapMemory=NULL;
97
98 //hBitmapbkMemory=NULL;
99
100 DeleteDC(hdcMemory);
101
102 ReleaseDC(hWnd,hDC);
103
104 //m_GIFImage->Draw(hDC,&rt,NULL);
105
106 return
转载于:https://www.cnblogs.com/IamEasy_Man/archive/2009/08/16/1547168.html
【转载】使用Imaging组件加载GIF动画相关推荐
- 加载数据时,页面显示正在加载的动画,支持移动端
最近在使用ionic3做一个移动端APP,在用户网络环境差的时候,查询数据会比较慢,这个时候需要模拟其他成熟的APP给页面上加入一个加载的动画.由于一开始我不知道ionic3本身已经提供了一套组件,所 ...
- WPF 加载等待动画
WPF 加载等待动画 原文:WPF 加载等待动画 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/qq_29844879/article/detail ...
- web.xml 组件加载顺序
转载自 web.xml 组件加载顺序 在配置项目组件的过程中, 了解Tomcat加载组件顺序很有必要. 例如某些框架如Quartz的集群功能需要数据库的支持, 数据库的加载肯定要在框架组件加载之前. ...
- [Swift通天遁地]五、高级扩展-(11)图像加载Loading动画效果的自定义和缓存
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ ➤微信公众号:山青咏芝(shanqingyongzhi) ➤博客园地址:山青咏芝(https://www.cnblog ...
- 【es】es Plugin 组件加载 PluginsService
1.概述 转载并且补充:[9]elasticsearch源码深入分析--Plugin组件加载 2.开篇 本篇开始将会详细解释Node实例化的过程中PluginsService的相关内容,PluginS ...
- android 图标弹跳动画,动效教程 | 5 分钟快速制作弹跳加载小动画
前言 今天墨染哥教你如何5分钟快速制作一个弹跳的加载小动画,如下图所示,这个小动画要快速做出来,需要解决解决两个技术难点,第一个是食物图标的弹跳,第二个是文本的弹跳. 食物图标的弹跳 话不多说,先看看 ...
- android 蒙层动画,Android酷炫加载进度动画
一.概述 本自定义动画进度酷炫View,是加载进度动画的自定义View,继承于ImageView来实现,主要实现蒙层加载进度的加载进度效果. 支持水平左右加载和垂直上下加载四个方向,同时也支持自定义蒙 ...
- React_lazy使用-组件加载前loading做优雅降级
当我们在渲染页面时,毫无疑问,需要一个加载的动画,在页面没有完全渲染前,展示加载效果. 此时我们需要封装一个加载组件. 1. 封装加载组件 components/Loading/index.js im ...
- 【vue】用WOW.js+animate.css实现页面滚动加载元素动画
一.场景 在很多的网站中,我们发现在滚动条滑动的时候一些元素显示出来的时候是有一些动画效果的,这样看起来页面更具有活力,增加用户体验.当然这些动画我们可以通过判断滚动条的位置或者判断元素距离可视窗口的 ...
最新文章
- group by 查找订单的最新状态 join
- 迪杰斯特拉算法。简单理解。内含示例
- python:读取excel数据
- WPF 的 ElementName 在 ContextMenu 中无法绑定成功?试试使用 x:Reference!
- python每日一题公众号_python每日一题总结4
- IDEA启动:Internal error. Please refer to https://jb.gg/ide/critical-startup-errors
- Qt界面程序嵌入另一个Qt界面程序[Linux]
- python数据科学包第三天(股票数据分析、时间事件日志)
- 红外光谱图解析知识大全(图文并茂)
- 天津人民优步司机当周奖励政策 (8.3-8.9)
- MongoDB安装教程(Win10Linux)
- 驼峰设计 宣传PPT代写
- 武汉旅游地图(zz)
- FBX格式转换为GLTF/GLB格式
- png,jpg转换为ico的方法
- 解决乐视电视投屏卡顿的问题
- 两种方法扫二维码下载APP,获取IPA安装包
- java毕设项目开源啦,springboot+Thymeleaf的仿豆瓣电影论坛系统
- [Keil] MDK5 集成开发环境搭建与注册破解
- html文本框下凹,【CSS】凹槽的写法
热门文章
- python 代码格式规范脚本_Python编码规范
- 浅析C++的三大循环-以100以内的质数求解为例
- 可网管交换机与非网管交换机的区别
- 【渝粤教育】国家开放大学2018年秋季 0273-22T中国现代文学 参考试题
- [渝粤教育] 西南科技大学 智能交通系统 在线考试复习资料
- 2021年春季学期期末统一考试 国际公法 试题
- oracle 群集 无存储,存储的群集注意事项 - 
Oracle® ZFS Storage Appliance 管理指南
- python学习与数据挖掘_Python学习之数据挖掘(三)
- kuka机器人焊接飞溅大_库卡机器人KCP4示教器屏幕校准方法
- toad查看oracle的plsql包,Oracle logminer 分析redo log(TOAD与PLSQL)