读真假美猴王有感400:GDI+中GIF图片的显示

来源:百度文库 编辑:偶看新闻 时间:2024/05/01 03:51:37
在GDI+中绘制GIF

GDI+中绘制一个图片的代码如下:
      void CMyWnd::OnPaint()      {      CPaintDC dc(this);      Graphics graphics(&dc); // Create a GDI+ graphics object            Image image(L"Test.Gif");  // Construct an image      graphics.DrawImage(&image, 0, 0, image.GetWidth(), image.GetHeight());      }      
Gif分为两种,一种是静态的,对于这种格式的Gif,在GDI+中无需采用任何方法就能够直接显示(上面的代码就属于这种情况)。另一种是动态的, 这种文件能够显示简单的动画。动态的实际上由多幅静态的组成,在显示Gif时,每幅图片按照一定的时间间隔依次进行显示,从而实现了动画效果。
我把GIF封装成了一个类ImageEx,这个类继承了GDI+中的Image类。我们首先要做的工作是判断GIF是动态的还是静态的。
bool ImageEx::TestForAnimatedGIF(){       UINT count = 0;       count = GetFrameDimensionsCount();       GUID* pDimensionIDs = new GUID[count];               // 得到子帧的对象列表       GetFrameDimensionsList(pDimensionIDs, count);            //获取总帧数    m_nFrameCount = GetFrameCount(&pDimensionIDs[0]);         // 假设图像具有属性条目 PropertyItemEquipMake.     // 获取此条目的大小.    int nSize = GetPropertyItemSize(PropertyTagFrameDelay);         // 为属性条目分配空间.    m_pPropertyItem = (PropertyItem*) malloc(nSize);    GetPropertyItem(PropertyTagFrameDelay, nSize, m_pPropertyItem);    delete pDimensionIDs;    return m_nFrameCount > 1;    }
m_pPropertyItem->value 是一个长整形数组, 每个长整形代表每帧的延时。由于获取的属性不同,GetPropertyItem会获得不同大小的对象, 因此要由用户来获得的对象大小,开辟与删除 GetPropertyItem相关的内存。对象的大小是通过GetPropertyItemSize 获取的,其参数是你所感兴趣的属性条目。 一旦获取了帧的数量与延时,我们就可生成一个线程来调用 DrawFrameGIF()来显示。
       bool ImageEx::DrawFrameGIF()       {       ::WaitForSingleObject(m_hPause, INFINITE);       GUID pageGuid = FrameDimensionTime;       long hmWidth = GetWidth();       long hmHeight = GetHeight();       HDC hDC = GetDC(m_hWnd);       if (hDC)       {       Graphics graphics(hDC);       graphics.DrawImage(this, m_rc.left, m_rc.top, hmWidth, hmHeight);       ReleaseDC(m_hWnd, hDC);       }       SelectActiveFrame(&pageGuid, m_nFramePosition++);        if (m_nFramePosition == m_nFrameCount)       m_nFramePosition = 0;              long lPause = ((long*) m_pPropertyItem->value)[m_nFramePosition] * 10;       DWORD dwErr = WaitForSingleObject(m_hExitEvent, lPause);       return dwErr == WAIT_OBJECT_0;       }       
三、效果图


图一 效果