1. 程式人生 > >視窗中顯示bmp圖片的過程

視窗中顯示bmp圖片的過程

建立步驟

我們首先大致瞭解下顯示點陣圖的基本步驟,主要有5步,如圖1所示:


                                                            圖1 點陣圖顯示步驟

對每個過程的解釋如下:

1.建立點陣圖

   利用CBitmap類構造一個位圖物件,然後利用LoadBitmap函式完成實際點陣圖資源和物件的關聯.

2.建立相容DC

   在OnDraw或OnEraseBkgnd函式的入參是CDC物件指標,指示了當前實際顯示裝置的相關資訊;我們利用CreateCompatible函式建立一個記憶體裝置上下文,和引數pDC所指定的DC相相容。記憶體裝置上下文實際上是一個記憶體塊,表示一個顯示的表面,

可以認為是虛擬的裝置顯示環境

3.將點陣圖選人相容DC中

   當相容的記憶體裝置上下文被建立時,它的表面是標準的一個單色畫素寬和一個單色畫素高,我們需要將具有有正確的寬度和高度的點陣圖選人相容DC,才能正確的顯示。

4.將相容DC中的點陣圖貼上到當前DC

    我們可以利用BitBlt函式或者StrechBlt函式完成相容DC中的影象到實際DC的搬移和顯示。

5.點陣圖顯示

     利用視窗繪製過程的兩個時機完成點陣圖顯示,一個視窗繪製過程包括兩個步驟:首先是利用畫刷擦除視窗背景,其次是再對視窗重新進行重繪;擦除是呼叫OnEraseBkgnd函式,重繪是呼叫OnDraw函式

函式說明

BitBlt函式是以1:1的比例完成拷貝,而StrechBlt函式則可以進行圖片的壓縮或者擴充套件,它們的函式宣告和引數函式如下所示,更加具體的資訊引數MSDN:

BitBlt函式宣告如下:

BOOL BitBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop );

返回值:函式成功,返回非零值,否則為0。
引數: 
x       指定目標矩形左上角的邏輯x座標。  
y       指定目標矩形左上角的邏輯y座標。  
nWidth  指定目標矩形和源點陣圖的寬度(邏輯單位)。  
nHeight 指定目標矩形和源點陣圖的高度(邏輯單位)。  
pSrcDC  指向CDC物件的指標,標識待拷貝點陣圖的裝置上下文。  
xSrc    指定源點陣圖左上角的邏輯X座標。  
ySrc    指定源點陣圖左上角的邏輯Y座標。  
dwRop   指定要執行的光柵操作 

StrechBlt函式宣告如下:
BOOL StretchBlt(
     int x,
     int y,
     int nWidth,
     int nHeight,
     CDC* pSrcDC,
     intxSrc,
     int ySrc,
     int nSrcWidth,
     int nSrcHeight,
     DWORD dwRop
     )

返回值:如果點陣圖已經繪製,則返回非零值,否則為0。
引數: 
x           目標矩形左上角的X邏輯座標。  
y           目標矩形左上角的Y邏輯座標。  
nWidth      目標矩形的寬度(邏輯單位)。  
nHeight     目標矩形的高度(邏輯單位)。  
pSrcDC      指定源裝置上下文。  
xSrc        源矩形左上角的X邏輯座標。  
ySrc        源矩形左上角的Y邏輯座標。  
nSrcWidth   源矩形的寬度(邏輯單位)。  
nSrcHeight  源矩形的高度(邏輯單位)。  
dwRop       指定光柵操作。

功能程式碼

我們這裡以OnEraseBKgnd訊息響應函式完成整個顯示功能,該函式在視類中進行響應,具體程式碼如下:

BOOL CCBmpViewView::OnEraseBkgnd(CDC* pDC)
{
    // TODO: 在此新增訊息處理程式程式碼和/或呼叫預設值

    //建立點陣圖物件
    CBitmap bitmap;
    bitmap.LoadBitmap(IDB_BITMAP1);

    //獲取點陣圖資訊
    BITMAP bmp;
    bitmap.GetBitmap(&bmp);

    //建立相容DC
    CDC dcCompatible;
    dcCompatible.CreateCompatibleDC(pDC);

    //將點陣圖選入相容DC
    dcCompatible.SelectObject(&bitmap);

    //向實際DC輸出圖片
    CRect rect;
    GetClientRect(&rect);
    //1比1格式輸出圖片
    //pDC->BitBlt(0,0,rect.Width(), rect.Height(),&dcCompatible,0,0,SRCCOPY);
    //適應實際視窗大小進行圖片壓縮或者拉伸輸出
    pDC->StretchBlt(0,0,rect.Width(), rect.Height(),&dcCompatible,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);
   
    return TRUE;
}
執行效果:


效果分析

通過兩種方式進行對比發現,若我們的點陣圖大小比視窗小,以OnEraseBkgnd函式和BitBlt函式進行輸出圖片,改變視窗大小會有視窗的殘留痕跡;若以OnDraw函式和BitBlt函式進行輸出則沒有這樣的問題,但是會帶來視覺上的閃爍;StrechBlt函式由於有壓縮或者拉伸造成圖片失真。