解压缩并在 PC 和 PPC 上显示动画 GIF






3.81/5 (5投票s)
一个用于显示动画 GIF 的类,手动扫描和解压缩。
引言
此处提供的代码将允许在 Windows 上在您的项目中显示动画 GIF 文件。它不依赖任何库来执行此操作,而是手动扫描 GIF 以确定其内容,解压缩图像数据,并在您选择的窗口上显示它。通过手动执行此操作,代码在 Win32 系统上具有一定程度的可移植性,允许相同的代码在桌面和 Pocket PC 应用程序中工作。
背景
在编写项目时,我经常需要显示某种动画,无论是作为用户状态消息还是为了丰富归属对话框。在多次手动使用计时器和图标切换图像之后,我需要一种更好、更灵活的方式。GIF 图像格式的流行及其显示动画的能力使其成为存储我的代码动画的首选。
Using the Code
您将与之交互的类是 gifDisplayer
; 它有四个方法来与所需的 GIF 文件交互。
//Calls the load from reader then prepairs bitmaps for display,
//a gif must be loaded before it can be displayed.
BOOL loadGif(CString filePath,
HDC hDCin,
BOOL animate,
HWND hWnd,
int multiplySizeBy,
int Xoffset,
int Yoffset);
BOOL loadGif(unsigned char* bufferIn,
unsigned long lengthIn,
HDC hDCin,
BOOL animate,
HWND hWnd,
int multiplySizeBy,
int Xoffset,
int Yoffset);
//An image must be loaded by calling the load method from the gifReader first.
BOOL displayGif();
//clean up.
void unloadGif();
可以同时使用此类的多个对象。多个动画可以同时绘制到同一个窗口。不支持在同一位置叠加多个动画。如果这样做,透明度将会丢失。
要使用该类,需要设置一些静态成员
#include "stdafx.h"
#include "gifDisplayer.h"
HANDLE gifDisplayer::hAccessMutex=0;
HANDLE gifDisplayer::hTimingThread=0;
int gifDisplayer::countOfObjects=0;
gifDisplayer* gifDisplayer::gifDisplayerObjectArray[MAX_SURFACES];
这从主要的 .cpp 文件完成,或从那里包含在一个文件中。
之后,您可以像通常那样从该类实例化对象
//The parameter is the starting size for the decompressed gif.
//This can be set small but a small size will make decompression take longer
//because the output will have to be grown many times.
gifDisplayer* gr=new gifDisplayer(100000);
gifDisplayer* gr2=new gifDisplayer(100000);
gifDisplayer* gr3=new gifDisplayer(100000);
在调用 loadGif(...)
或 displayGif()
之前,确保您的窗口已正确绘制很重要。这是因为为了允许 GIF 在您的窗口上看起来是透明的,窗口的内容将被复制以形成 GIF 将显示的基底。为此,我在创建窗口后向窗口发送一条消息,允许延迟以进行初始绘制。
switch (message)
{
case SETUP_MESSAGE:
{
//on a mobile device this can be a bit slow
//so its a good idea to show a wait cursor.
SetCursor(LoadCursor (NULL,IDC_WAIT));
//load and display three gifs.
gr->loadGif(gifPath,//the path of the file
surfaceDC,//the device context of the window
TRUE,//do you want to animate?
hSurfaceWindow,//the handle of the window
1,//scale the gif by a factor of 1 (possible values 1,2,3,4...)
50,//x position
100);//y position
gr->displayGif();
gr2->loadGif(gifPath2,
surfaceDC,
TRUE,
hSurfaceWindow,1,150,200);
gr2->displayGif();
gr3->loadGif(gifPath3,
surfaceDC,
TRUE,
hSurfaceWindow,2,0,0);
gr3->displayGif();
SetCursor(0);
}
break;
在结束您的程序之前,请记住在每个对象上调用 unloadGif()
。
gifDisplayer
类继承自我编写的许多其他类。您只需要像在演示中那样将它们包含在您的项目中即可。我以这种方式拆分了功能,因为扫描、解压缩和显示是截然不同的部分,更适合于独立。请注意,我在代码中使用 MFC CString
s 和 CObjectArray
s。项目本身是 Win32,不是 MFC 项目。需要在项目设置和包含文件中进行一些更改,以使其在 Win32 代码中工作。如果您想完全摆脱 MFC,很容易用您自己的类替换这些类。
关注点
此项目中的所有代码均基于 Steve Blackstock 的文档“LZWand GIF explained”和 CompuServe GIF 标准。尽管这些文档不包含任何 C++ 代码,但它们是对 GIF 的准确描述。
历史
- 提交时间:2008 年 3 月 24 日。