MFC中显示 .bmp格式的位图
最近在看VisualC++ 圖像處理的書籍,表示一直在從基礎做起,今天就記錄一個簡單功能的實現,顯示.bmp格式的位圖。
首先需要理解的是窗口創建的過程包括兩個步驟:首先擦除窗口的背景,然后在對窗口進行重新繪制。
一般而言,對于單文檔或多文檔的MFC程序,顯示圖像的代碼要放在OnDraw函數之中。剛剛說過,窗口重繪時,要先將窗口的背景擦除,也就是發送WM_ERASEBKGND消息,然后用OnEraseBkgnd()函數處理這個消息,所以我們的顯示圖像的代碼也可以放在這個函數之中。當然,這里只是為了實現顯示位圖這一個功能,在實際工程中,要根據實際情況,選擇代碼放置的地方。
下面先給出代碼,然后一行一行地詳細解釋:
BOOL CLoadBitmapView::OnEraseBkgnd(CDC* pDC)
{
?// TODO: 在此添加消息處理程序代碼和/或調用默認值
?//return FALSE;
?HBITMAP hBit;
?hBit=(HBITMAP) LoadImage(NULL,_T("D:\\Axing.bmp"),IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);?//載入圖像
?CBitmap cBit;
?cBit.Attach(hBit);
?CDC MemDC;
?MemDC.CreateCompatibleDC(pDC);?//創建與當前設備描述表相適應的內存DC
?BITMAP bitmap;
?cBit.GetBitmap(&bitmap);
?CBitmap *oldBit;
?oldBit=MemDC.SelectObject(&cBit);
?CRect rect;
?GetClientRect(&rect);
?pDC->BitBlt(100,100,rect.Width()/2.5,rect.Height(),&MemDC,0,0,SRCCOPY);
?return TRUE;
?//return CView::OnEraseBkgnd(pDC);
}
?
?
首先來解釋一下HBITMAP、CBitmap、BITMAP三者之間的關系。
HBITMAP是圖片的句柄,CBitmap是MFC定義的一個類,在這個類中對HBITMAP進行了封裝,BITMAP則是一個結構體,這個結構體中保存著位圖的各種信息(如寬度和高度等)。有三個函數是和這三個類型息息相關的。
第一個:Attach(),這個函數是CBitmap類的成員函數,作用就是將HBITMAP類型轉換成CBitmap類型。我們在代碼中會用到它。
第二個:GetBitmap(),這個函數也是CBitmap類的成員函數,作用就是獲取位圖的信息,并將位圖的信息保存在BITMAP 結構指針中。
第三個:GetObject(),這個函數的作用就是,從HBITMAP句柄中獲取BITMAP結構。
這三個函數的具體用法,詳細說明在這里就不贅述了,用的時候可以百度一下很方便的。
?
我們先建立了一個HBITMAP類型的句柄,然后用LoadImage()函數來載入一個位圖,并保存位圖的句柄。之后,創建一個CBitmap類的對象,然后將HBITMAP轉換成CBitmap對象(用Attach()函數)。之后用CReateCompatibleDC()函數,創建一個與當前設備上下文相兼容的內存DC。
問題來了,為什么要創建這個內存DC呢?
其實,這個內存DC的作用就是緩沖。如果需要對屏幕進行比較多的GUI操作,如果直接對屏幕DC進行操作,會導致同顯示內存之間的過于頻繁的數據交換,于是程序運行效率將受到嚴重影響。任何繪圖的過程都是這樣,要完成一幅圖像的顯示,總是在顯示終端上依次繪制每個像素點,以形成完整的圖像。我們在內存中虛擬一塊畫布(就是內存DC),繪圖時僅僅對內存進行操作。待政府圖像繪制完成時在整體復制到屏幕上,這樣避免了外設和內存之間頻繁的數據交換,程序的運行效率會提高很多。這就是使用CreateCompatibleDC()函數創建內存DC 的作用。
接著,我們將位圖選入到內存DC中(MemDC.SelectObject(&cBit)),這一步也是相當重要的。因為當兼容的內存DC創建的時候,他的顯示表面是標準的一個單色像素寬和單色像素高。在應用程可以使用內存DC進行繪圖操作之前,必須將一個具有正確高度和寬度的位圖,選入到內存DC中,這時內存設備上下文顯示表面的大小就由當前選入的位圖決定了。
之后CRect rect;GetClientRect(&rect);用于獲取客戶區。
最后用BitBlt()函數將內存DC中的內容復制到當前DC中,顯示位圖完畢。
這里要解釋一下BitBlt函數,它的函數原型為:
BOOLBitBlt(int x,int y,int nWidth,int nHeight,CDC*pSrcDC,int xSrc,int ySrc,DWORDdwRop);
參數x、y表示目的DC(當前設備上下文)矩形區域的左上角坐標,nWidth,nHeight,表示矩形區域的寬和高,pSRCDC則是源DC(內存DC)的指針,xSrc和ySrc表示源DC矩形區域的左上角坐標。我們可以看到并沒有參數表示源目的矩形區域的寬和高,這樣,區域之間的復制只能是1:1的,所以當圖像比較大時,只能顯示圖像的一部分。為了解決這個問題,可以用StretchBlt()函數,這個函數和BitBlt()函數的功能基本一致,只是可以對圖像進行伸縮變換,這是因為在StretchBlt()函數中增加了兩個參數,表示源DC矩形區域的大小。所以上面的代碼可以改成
?pDC->StretchBlt(100,100,rect.Width()/2.5,rect.Height(),&MemDC,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);
。
這樣就可以顯示整張位圖了。
?
轉載于:https://www.cnblogs.com/qingergege/p/4964951.html
總結
以上是生活随笔為你收集整理的MFC中显示 .bmp格式的位图的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 唱吧房间个性公告签名
- 下一篇: 一次性补交养老保险15年要交多少钱,退休