【转载】使用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方法,此時畫出的就是指定的那個圖像塊圖像。
?? ? 部分代碼:
?? ? 文件到流的轉化
Code
??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)方法?
Code
??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动画的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 很久没来了,嘿嘿 问候一下大家,O(∩_
- 下一篇: 学习《Building Applicat