CImage類是ATL和MFC共用的一個類,其頭文件為atlimage.h,主要用於圖片文件的打開,顯示與保存。這里需要注意的是,在VS2010 和VS2012的MFC編程中,不需要將頭文件包含進來。MFC中要使用CImage類,必須先將頭文件包含進來,可以包含在當前代碼的CPP文件中,也可以包含在所屬類的頭文件中,不過最好還是包含在工程的stdafx.h文件中。CImage總共有39個成員函數,下面將在CImage的功能實現中慢慢講解。
1、保存圖片
保存圖片只有一個函數,就是Save函數,該函數有兩個參數,一個是文件的完整路徑和文件名,一個是文件的擴展名。但是如果只有保存和顯示圖片功能,CImage的Save函數發揮不了太大的作用,不過是一個轉存文件的工具。CImage的強大之處在於可以對圖片進行修改,再進行保存。
修改圖片的函數有這么3個函數可以修改圖片,都是像素級的操作。這三個函數分別為SetPixel,SetPixelRGB,SetPixelIndexed。可以通過雙重循環對屏幕進行逐點掃描,並把像素顏色值保存到CImage對象中達到截屏的目的。
我們可以用一段很簡單的代碼來實現將DC(設備上下文)里繪制的圖形存入圖片文件中。[2]基本的思想是先初始化一個CImage對象,再為它設定大小和位數,也就是圖片大小和圖片的色彩總數,再用設備上下文繪圖。繪制完圖形后再建立另外一個設備上下文對象,稱為目的DC,將之前繪圖的DC稱為源DC,目的DC必須與CImage對象關聯起來,然后利用BitBlt函數和其他函數將繪圖DC的內容拷貝到目的DC中,最后將CImage對象保存到文件中,以下是代碼實現(VS2010支持中文變量名):
1 CRect rect; 2 this->GetClientRect(rect); 3 CImage image; 4 image.Create(rect.Width(),rect.Height(),24); 5 CDC* DCpoint=this->GetDC(); 6 DCpoint->Ellipse(20,20,200,200); 7 CDC dstDC; 8 dstDC.CreateCompatibleDC(DCpoint); 9 dstDC.SelectObject(image); 10 dstDC.BitBlt(0,0,rect.Width(),rect.Height(),DCpoint,0,0,SRCCOPY); 11 image.Save(L"D:\\用戶目錄\\Pictures\\寫圖片文件.jpg");
2、顯示圖片
首先看下面這段代碼
1 CImage image; 2 image.Load(L"D:\\用戶目錄\\Pictures\\example.jpg"); 3 image.Draw(GetDC()->m_hDC,CRect(0,0,320,240)); 4 CImage類支持以Load方法讀取本地磁盤上的文件,並用Draw方法來顯示圖片。CIamge類的成員函數中還有很多可以實現顯示圖片。例如BitBlt辦法。如以下代碼: 5 image.BitBlt(GetDC()->m_hDC,0,0,320,240,0,0,SRCCOPY);
Bitblt方法同CDC類的Bitblt函數一樣,是一比一地復制圖像並顯示在屏幕上,支持對源圖像取反,也就是反色顯示。這樣功能通過BitBlt的最后一個參數來實現,比如參數為NOTSRCCOPY就是反色顯示。
MaskBlt可以將圖片與目的圖片進行特殊的光柵操作並進行掩碼處理。
PlgBlt函數可以將圖片拉伸成平行四邊形進行顯示。
StretchBlt函數可以將圖片進行拉伸顯示。
3、創建圖片
CImage的Creat函數和CreatEx函數用來創建空白圖片,編程人員可以利用這個函數來創建圖像,並添加代碼讓用戶可以使用鼠標來改變CImage對象的像素顏色,以實現類似於windows畫圖的功能。
文章來源:百度百科(http://baike.baidu.com/view/5725174.htm?fr=wordsearch)
4、CImage顯示透明PNG
在做項目的時候,需要用到透明的png格式的圖片,使用CImage類是個不錯的選擇,但在使用該類的時候,發現顯示出來的並不是透明背景的圖片, 而且一些黑色邊加一大片白色背景的圖片,這是怎么回事呢?用ps來看的時候明明就是透明的。於是google一番,找到一些關於這類問題的看法:
以下為轉述:
PNG 圖片的透明背景總是一片白色,后來才發現這其實是微軟GDI+的設計問題,PNG圖片是ARGB,使用GDI+載入圖片的時候,GDI+會默認已經進行了 預剩運算(PARGB),即每象素的實際值是已經和ALPHA值按比例相乘的結果,實際上它根本就沒有做預乘,在使用透明圖片的象素ALPHA通道的時 候,CImage內部正是調用的AlphaBlend,沒有預乘的圖當作預乘的圖片處理的結果就是這相當於一張和純白背景進行了預剩,所以圖象總是出現白 色背景。
雖然找到了問題,但是還是要解決的。於是又google一番,使用如下代碼來處理:
1 CImage img; 2 HRESULT result = img.Load(_T("(你的工作路徑)//keys_base.png")); 3 for(int i = 0; i < img.GetWidth(); i++) 4 { 5 for(int j = 0; j < img.GetHeight(); j++) 6 { 7 unsigned char* pucColor = reinterpret_cast<unsigned char *>(img.GetPixelAddress(i , j)); 8 pucColor[0] = pucColor[0] * pucColor[3] / 255; 9 pucColor[1] = pucColor[1] * pucColor[3] / 255; 10 pucColor[2] = pucColor[2] * pucColor[3] / 255; 11 } 12 }