多页图像是指图像中包含有多个图形页。每页可以看作图像帧。这些图像帧通过连续的显示就形成了一副动画。比如
GIF
文件。
GDI+
的
Image
对象提供了直接的对
GIF
、
TIF
文件格式的支持。调用
Image
对象的成员函数
GetFrameDimensionsCount
可以得到
Image
对象的
Dimension
数。每个
Dimension
通过一个
GUID
标示。函数
GetFrameDimensionsList
可以返回所有
Dimension
的
GUID
值。第一个
GUID
值保存在函数参数
pDimensionsIDs
数组的索引
0
处。
GetFrameCount
可以得到每个
Dimension
里有多少个
Frame
。简单示例代码:
Image* image = new Image(L"Multiframe.gif");
UINT count = 0;
count = image->GetFrameDimensionsCount();
GUID *pDimensionIDs=(GUID*)new GUID[count];
image->GetFrameDimensionsList(pDimensionIDs, count);
WCHAR strGuid[39];
StringFromGUID2(pDimensionIDs[0], strGuid, 39);
UINT frameCount=image->GetFrameCount(&pDimensionIDs[0]);
Image* image = new Image(L"Multiframe.gif");
UINT count = 0;
count = image->GetFrameDimensionsCount();
GUID *pDimensionIDs=(GUID*)new GUID[count];
image->GetFrameDimensionsList(pDimensionIDs, count);
WCHAR strGuid[39];
StringFromGUID2(pDimensionIDs[0], strGuid, 39);
UINT frameCount=image->GetFrameCount(&pDimensionIDs[0]);
delete []pDimensionIDs;
并不是所有的 GIF 文件都是含有多帧的,所以我们在显示 GIF 的时候可以通过上面的代码根据 frameCount 的值判断这个 GIF 文件是否有多个帧。
并不是所有的 GIF 文件都是含有多帧的,所以我们在显示 GIF 的时候可以通过上面的代码根据 frameCount 的值判断这个 GIF 文件是否有多个帧。
在确认有多个帧的图像以后,还要得到每帧图像显示的间隔时间。
GDI+
的
Image
对象提供了
GetPropertyItem
获取图像的属性。
GetPropertyItem
函数需要用户传递数据返回缓冲区和大小。所以在使用前先用
GetPropertyItemSize
得到需要的缓冲区大小,分配空间后再取得属性数据。
//PropertyTagFrameDelay
是
GDI+
中预定义的一个
GIG
属性
ID
值,表示标签帧数据的延迟时间
int size = GetPropertySize(PropertyTagFrameDelay);
PropertyItem* pItem = NULL;
pItem = (PropertyItem*)malloc(size);
image->GetPropertyItem(PropertyTagFrameDelay,size,pItem);
这样就把所有和 PropertyTagFrameDelay 属性相关的数据取到了 pItem 中。然后通过 pItem 访问结构中的 value 。每两帧图像之间的间隔时间是不一定相同的,所以还需要得到当前正显示的帧图像的索引值。最后调用 Image 对象的 DrawImage 函数把每帧图像画出来。简单代码如下:
int fcount=0;
//Guid 的值在显示 GIF 为 FrameDimensionTime ,显示 TIF 时为 FrameDimensionPage
GUID Guid = FrameDimensionTime;
while(thue)
{
Graphics gh(hDC); //hDC 是外部传入的画图 DC
gh.DrawImage(image,0,0,image->GetWidth(),image->GetHeight());
// 重新设置当前的活动数据帧
image->SelectActiveFrame(&Guid,fcount++);
if(fcount == frameCount) //frameCount 是上面 GetFrameCount 返回值
fcount= 0; // 如果到了最后一帧数据又重新开始
// 计算此帧要延迟的时间
long lPause = ((long*)pItem->value)[fcount]*10;
Sleep(lPause); // 这里简单使用了 sleep
}
PropertyItem* pItem = NULL;
pItem = (PropertyItem*)malloc(size);
image->GetPropertyItem(PropertyTagFrameDelay,size,pItem);
这样就把所有和 PropertyTagFrameDelay 属性相关的数据取到了 pItem 中。然后通过 pItem 访问结构中的 value 。每两帧图像之间的间隔时间是不一定相同的,所以还需要得到当前正显示的帧图像的索引值。最后调用 Image 对象的 DrawImage 函数把每帧图像画出来。简单代码如下:
int fcount=0;
//Guid 的值在显示 GIF 为 FrameDimensionTime ,显示 TIF 时为 FrameDimensionPage
GUID Guid = FrameDimensionTime;
while(thue)
{
Graphics gh(hDC); //hDC 是外部传入的画图 DC
gh.DrawImage(image,0,0,image->GetWidth(),image->GetHeight());
// 重新设置当前的活动数据帧
image->SelectActiveFrame(&Guid,fcount++);
if(fcount == frameCount) //frameCount 是上面 GetFrameCount 返回值
fcount= 0; // 如果到了最后一帧数据又重新开始
// 计算此帧要延迟的时间
long lPause = ((long*)pItem->value)[fcount]*10;
Sleep(lPause); // 这里简单使用了 sleep
}