在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分為兩種,一種是靜態(tài)的,對于這種格式的Gif,在GDI+中無需采用任何方法就能夠直接顯示(上面的代碼就屬于這種情況)。另一種是動態(tài)的, 這種文件能夠顯示簡單的動畫。動態(tài)的實際上由多幅靜態(tài)的組成,在顯示Gif時,每幅圖片按照一定的時間間隔依次進(jìn)行顯示,從而實現(xiàn)了動畫效果。
我把GIF封裝成了一個類ImageEx,這個類繼承了GDI+中的Image類。我們首先要做的工作是判斷GIF是動態(tài)的還是靜態(tài)的。
bool ImageEx::TestForAnimatedGIF(){ UINT count = 0; count = GetFrameDimensionsCount(); GUID* pDimensionIDs = new GUID[count]; // 得到子幀的對象列表 GetFrameDimensionsList(pDimensionIDs, count); //獲取總幀數(shù) m_nFrameCount = GetFrameCount(&pDimensionIDs[0]); // 假設(shè)圖像具有屬性條目 PropertyItemEquipMake. // 獲取此條目的大小. int nSize = GetPropertyItemSize(PropertyTagFrameDelay); // 為屬性條目分配空間. m_pPropertyItem = (PropertyItem*) malloc(nSize); GetPropertyItem(PropertyTagFrameDelay, nSize, m_pPropertyItem); delete pDimensionIDs; return m_nFrameCount > 1; }
m_pPropertyItem->value 是一個長整形數(shù)組, 每個長整形代表每幀的延時。由于獲取的屬性不同,GetPropertyItem會獲得不同大小的對象, 因此要由用戶來獲得的對象大小,開辟與刪除 GetPropertyItem相關(guān)的內(nèi)存。對象的大小是通過GetPropertyItemSize 獲取的,其參數(shù)是你所感興趣的屬性條目。 一旦獲取了幀的數(shù)量與延時,我們就可生成一個線程來調(diào)用 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; }
三、效果圖圖一 效果
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請
點擊舉報。