天天看點

VC下加載多種格式圖檔的方法總結IPicture, CxImage, CImage(AtlImage), CPictureEx

盡管VC有提供相應的API和類來操作bmp位圖、圖示和(增強)元檔案,但卻不支援jpg、gif和png等格式的圖檔,而這幾種格式卻是常常要用到的。這裡我給大家介紹兩種辦法來操作這些格式的圖檔。

1.用API OleLoadPicture來加載JPG、GIF格式的圖檔(注:不支援PNG格式,另外GIF隻能加載第一幀,且不支援透明)

OleLoadPicture 函數實際上建立了一個IPicture類型的COM接口對象,然後我們可以通過這個COM接口來操作圖檔(實際上你也可以用API OleCreatePictureIndirect來加載圖檔,不過相比而言OleLoadPicture函數簡化了基于流的IPicture對象的建立),下面是示例代碼:(注:由于隻是用來示例,代碼中省去了出錯情況的處理)

<pre class="cpp" name="code">#include <olectl.h></pre>/*     *如下代碼段實作的功能是從指定的路徑中讀取圖檔,并顯示出來     */ void DisplayImage(HDC hDC, LPCTSTR szImagePath) {             HANDLE hFile=CreateFile(szImagePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); //從指定的路徑szImagePath中讀取檔案句柄             DWORD dwFileSize=GetFileSize(hFile, NULL); //獲得圖檔檔案的大小,用來配置設定全局記憶體             HGLOBAL hImageMemory=GlobalAlloc(GMEM_MOVEABLE, dwFileSize); //給圖檔配置設定全局記憶體             void *pImageMemory=GlobalLock(hImageMemory); //鎖定記憶體             DWORD dwReadedSize; //儲存實際讀取的檔案大小             ReadFile(hFile, pImageMemory, dwFileSize, &dwReadedSize, NULL); //讀取圖檔到全局記憶體當中             GlobalUnlock(hImageMemory); //解鎖記憶體             CloseHandle(hFile); //關閉檔案句柄                  IStream *pIStream;//建立一個IStream接口指針,用來儲存圖檔流             IPicture *pIPicture;//建立一個IPicture接口指針,表示圖檔對象             CreateStreamOnHGlobal(hImageMemory, false, &pIStream); //用全局記憶體初使化IStream接口指針             OleLoadPicture(pIStream, 0, false, IID_IPicture, (LPVOID*)&(pIPicture));//用OleLoadPicture獲得IPicture接口指針                  //得到IPicture COM接口對象後,你就可以進行獲得圖檔資訊、顯示圖檔等操作             OLE_XSIZE_HIMETRIC hmWidth;             OLE_YSIZE_HIMETRIC hmHeight;             pIPicture->get_Width(&hmWidth); //用接口方法獲得圖檔的寬和高             pIPicture->get_Height(&hmHeight);             pIPicture->Render(hDC,0,0,100,100,0,hmHeight,hmWidth,-hmHeight,NULL); //在指定的DC上繪出圖檔                  GlobalFree(hImageMemory); //釋放全局記憶體             pIStream->Release(); //釋放pIStream             pIPicture->Release(); //釋放pIPicture     }   

2.利用第三方的開發庫來操作圖檔

void DisplayImage(HDC hDC, CString fileName)   

{   

            CString fileExt; //圖檔的擴充名   

            int len = fileName.GetLength();   

            for(int i=len-1; i>=0; i--) //得到圖檔的擴充名   

            {   

                    if(fileName[ i ] == '.')   

                    {   

                            fileExt=fileName.Mid(i+1);   

                            break;   

                    }   

            }   

            fileExt.MakeLower(); //将擴充名轉為小寫   

            if(fileExt != _T(""))   

                    //建立CxImage對象,其中靜态方法CxImage::GetTypeIdFromName用來根據擴充名獲得圖檔格式的ID代表   

                    CxImage image(fileName,CxImage::GetTypeIdFromName(fileExt));   

                    if(image.IsValid())   

                            image.Draw(hDC);   

                            image.Destroy();   

}   

3 提供一中更簡單的方法

VC MFC 提供的 API LoadBitmap / LoadImage 類 CBitmap 等都隻能操作 BMP 位圖,圖示。對于其他常用的 JPG / JPEG / GIF / PNG 格式,它無能為力。VC 下怎樣才能加載各種非 BMP 格式的圖檔呢? 下面介紹一種最簡單的辦法。用 CImage 類的 Load 函數加載圖檔,之後用 Detach 取得 HBITMAP 句柄。取得圖檔的HBITMAP 句柄後就可以像操作 BMP 圖檔一樣處理 JPG / JPEG / GIF / PNG 格式的圖檔了。具體代碼如下: 

#include <atlimage.h>   

CImage img;   

HRESULT ret = img.Load(filename ); // filename 是要加載的檔案名(包含路徑)   

HBITMAP bitmap = img.Detach();   

//像操作 BMP 圖檔一樣處理圖檔  

但這些網上的方法還是有些問題,比如gif不能動态的顯示

下面說一下詳細步驟吧:

 1。下載下傳 PictureEx.h和PictureEx.cpp兩個檔案

把這兩個檔案放在工程的檔案夾裡面,然後在将這兩個檔案添加到工程裡面去,這樣你的工程裡就多了一個類了:CPictureEx

2.将你要加載的GIF圖檔添加到項目檔案夾裡,這裡我命名為:"inter.gif"

3。在試圖類的頭檔案裡添加:  

#include "PictureEx.h"  

定義一個對象: 

CPictureEx m_GifPic;  

4.在視圖類的OnCreate中建立 CPictureEx 對象并加載圖檔:

<pre class="cpp" name="code">m_GifPic.Create(NULL,WS_CHILD | WS_VISIBLE |SS_ENHMETAFILE,CRect(50,50,100,100),this,1234);  

m_GifPic.Load(_T("inter.gif"));  

m_GifPic.ShowWindow(SW_HIDE);//SW_SHOW  

</pre>  

注意:這一步驟不要在OnDraw裡面實作,否則會出現錯誤,我一開始時一直有問題就是這個原因,還有load必須在movewindow(下一步的函數)之前,否則不會顯示圖檔,還有就是load也可以放到ondraw裡面去,但是那麼做的話速度明顯不行了。

5。在ondraw裡改變視窗位置并顯示圖檔

m_GifPic.Create(NULL,WS_CHILD | WS_VISIBLE |SS_ENHMETAFILE,CRect(50,50,100,100),this,1234);  

CRect rc =CRect(100,400,150,450);  

m_GifPic.MoveWindow(&rc,true);  

m_GifPic.Draw();  

m_GifPic.ShowWindow(SW_SHOW);  

這裡還有一個基于對話框加載GIF圖檔的例子,添加了圖檔連結和滑鼠變換的功能。

下面是詳細的程式設計過程:

1. 建立項目:在VC6中用MFC建立一個基于對話框的GifDemo應用程式,接受所有預設選項即可;

2.在項目中插入檔案:把PictureEx.h,PictureEx.cpp檔案copy 到項目檔案夾下,Project->Add to Project->Files中選上PictureEx.h,PictureEx.cpp, Insert;

3.加入圖檔控件:從對話框控件中把Picture Control(圖檔控件)拖入主對話框中,修改其屬性:ID:IDC_GIF,TYPE:Rectangle,其餘接受預設選項。再在ClassWiard中為IDF_GIF加入CSatic控制變量m_GifPic, 注意看一下,GifDemoDlg.h中是否加上了#include "PictureEx.h"(由ClassWiard加入)。然後将CSatic m_GifPic;更改成CPictureEx m_GifPic;

4.加載動畫檔案:先将要加載的動畫檔案放到 res 資源檔案夾下,再将其Import進項目中,由于MFC隻支援256BMP檔案的圖檔,是以,我們要建立一個圖檔類型:"GIF",我在這裡将我網站的宣傳圖檔roaring.gif放進去 (希望大家多支援),并将其ID修改成:IDR_GIFROARING。

____________________________________

import(導入)gif動畫的詳細過程:

在resourceview視窗中,單擊滑鼠右鍵,在出現的環境菜單中選擇“import...”指令,會出現“import resource”選擇檔案對話框,檔案類型選擇“所有檔案(*.*)”,open as 選項為"auto",再選擇動畫檔案所在目錄,選上要載入的動畫檔案 roaring.gif,再單擊 import,由于gif動畫類型不是vc預設的檔案類型,這時會出現"custom resource type"對話框,鍵入“"gif"”,再單擊ok,然後再修改其id。

________________________________________________________________

5.在程式的适當位置添入加載代碼: 這裡,我們在CGifDemoDlg::OnInitDialog()函數中加入如下代碼:

// TODO: Add extra initialization here  

if (m_GifPic.Load(MAKEINTRESOURCE(IDR_GIFROARING),_T("Gif")))  

如果僅僅把動畫載入,到這就可以了,運作一下,應該看看您的的成果了。

下面附帶說說如何将這幅動畫制作成超連結,以後,咱們也可以宣傳自已的公司、網站或産品了。

6.利用ClassWiard加入一個LButtonDown滑鼠左鍵消息處理函數CGifDemoDlg::OnLButtonDown(UINT nFlags, CPoint point),  添入如下代碼:

void CGifDemoDlg::OnLButtonDown(UINT nFlags, CPoint point)   

{  

// TODO: Add your message handler code here and/or call default  

CRect rect;  

m_GifPic.GetWindowRect(&rect);  

ScreenToClient(&rect);  

if (rect.PtInRect(point))  

ShellExecute(AfxGetMainWnd()->m_hWnd,_T("open"),  

_T("http://roaringwind.best.163.com"),_T(""),NULL,0);  

CDialog::OnLButtonDown(nFlags, point);  

}  

我在這兒将我首頁的位址放上了,運作,點選動畫圖檔就能進入我的站點的了。當然要是能象所有的超連結一樣,能将滑鼠變成手形,就更好了。

7.改變滑鼠形狀:将一個滑鼠檔案放在res檔案夾中,IMPORT,ID:IDC_CURSOR1,利用ClassWiard加入一個WM_SETCURSOR消息處理函數CGifDemoDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message),  添入如下代碼:

BOOL CGifDemoDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)   

CPoint point;  

GetCursorPos(&point);  

ScreenToClient(&point);  

if (rect.PtInRect(point) && m_hCursor)  

SetCursor(m_hCursor);  

return TRUE;  

};  

return CDialog::OnSetCursor(pWnd, nHitTest, message);  

VC下加載多種格式圖檔的方法總結IPicture, CxImage, CImage(AtlImage), CPictureEx

<a target="_blank"> </a>

繼續閱讀