<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    依賴于設備的位圖(DDB) ,CreateCompatibleBitmap用法

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    DDB(Device-dependent bitmap)依賴于具體設備,這主要體現在以下兩個方面:

    •  

      DDB的顏色模式必需與輸出設備相一致。例如,如果當前的顯示設備是256色模式,那么DDB必然也是256色的,即一個像素用一個字節表示。

    •  

      在256色以下的位圖中存儲的像素值是系統調色板的索引,其顏色依賴于系統調色板。

     

     

    由于DDB高度依賴輸出設備,所以DDB只能存在于內存中,它要么在視頻內存中,要么在系統內存中。

     

    11.3.1 DDB的創建

    MFC的CBitmap類封裝了DDB。該類提供了幾個函數用來創建DDB:

     

    BOOL LoadBitmap( LPCTSTR lpszResourceName );

    BOOL LoadBitmap( UINT nIDResource );

    該函數從資源中載入一幅位圖,若載入成功則返回TRUE。資源位圖實際上是一個DIB,該函數在載入時把它轉換成了DDB。

    BOOL CreateBitmap( int nWidth, int nHeight, UINT nPlanes, UINT nBitcount, const void* lpBits );

    該函數用來創建一幅空白的DDB。參數nWidth和nHeight以像素為單位說明了位圖的寬度和高度。nPlanes是DDB的色平面數,nBitcount是每個色平面的顏色位數。一般來說,nPlanes為1,而nBitcount代表DDB中每個像素值所占的位數,但在創建16色DDB時,nPlanes為4,而nBitcount為1。參數lpBits指向存儲像素陣列的數組,該數組應該逐行存儲位圖的每個像素值。注意,數組中每行像素的數目必需是偶數個字節,如果是奇數,則應該用0補足。若創建成功函數返回TRUE。

    BOOL CreateCompatibleBitmap( CDC* pDC, int nWidth, int nHeight );

    該函數創建一個與指定設備上下文兼容的DDB。參數pDC指向一個設備上下文,nWidth和nHeight是DDB的尺寸。若創建成功函數返回TRUE。

     

     

    可以調用CBitmap的成員函數GetBitmap來查詢DDB的各種屬性(如尺寸):

     

    int GetBitmap( BITMAP* pBitMap );

    該函數用來獲得與DDB有關的信息,參數pBitMap指向一個BITMAP結構。BITMAP結構的定義為:

     

    typedef struct tagBITMAP {

    LONG bmType; //必需為0

    LONG bmWidth; //位圖的寬度(以像素為單位)

    LONG bmHeight; //位圖的高度(以像素為單位)

    LONG bmWidthBytes; //每一掃描行所需的字節數,應是偶數

    WORD bmPlanes; //色平面數

    WORD bmBitsPixel; //色平面的顏色位數

    LPVOID bmBits; //指向存儲像素陣列的數組

    } BITMAP;

     

     

    11.3.2 DDB的用途

      DDB的主要用途是保存位圖。要保存的位圖可以來自資源位圖,也可以是一個繪圖的結果。

      前面說過,在256色以下的顯示模式中,DDB中的像素值是系統調色板的索引。一般在系統調色板中除了保留的20種靜態顏色外,其它表項都有可能被應用程序改變。如果DDB中有一些像素值是指向20種靜態顏色以外的顏色,那么該位圖的顏色將是不穩定的。因此,DDB不能用來長期存儲色彩豐富的位圖。如果位圖使用的大部分顏色都是20種保留色,則該位圖可以用CBitmap對象保存在內存中。例如,用CDC::LoadBitmap載入的資源位圖一般都是顏色較簡單的位圖,對于那些顏色比較豐富的位圖,只有使用下面將要介紹的DIB才能長期保存。

    在窗口中顯示DDB的方法有些特別,其過程分以下幾步:

     

    構建一個CDC對象,然后調用CDC::CreateCompatibleDC創建一個兼容的內存設備上下文。

    調用CDC::SelectObject將DDB選入內存設備上下文中。

    調用CDC::BitBlt或CDC::StretchBlt將DDB從內存設備上下文中輸出到窗口的設備上下文中。

    調用CDC::SelectObject把原來的DDB選入到內存設備上下文中并使新DDB脫離出來。

     

     

    下面這段代碼在視圖中顯示了一個DDB:

     

    void CMyView::OnDraw( CDC* pDC)

    {

    . . .

    CDC MemDC;

    CBitmap *oldBmp;

    BITMAP bmpInfo;

    int bmWidth,bmHeight;

    MemDC.CreateCompatibleDC(pDC);

    oldBmp=MemDC.SelectObject(&m_Bitmap); //m_Bitmap是一個CBitmap對象

    m_Bitmap.GetBitmap(&bmpInfo); //獲取位圖的尺寸

    bmWidth=bmpInfo.bmWidth;

    bmHeight=bmpInfo.bmHeight;

    pDC->BitBlt(0,0,bmWidth,bmHeight,&MemDC,0,0,SRCCOPY);

    MemDC.SelectObject(oldBmp); //使位圖m_Bitmap脫離設備上下文

    . . .

    }

     

    函數CDC::BitBlt的聲明為:

     

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

     

      該函數把源設備上下文中的位圖復制到本身的設備上下文中,兩個設備上下文可以是內存設備上下文,也可以是同一個設備上下文。參數x和y是目的矩形的邏輯坐標,參數nWidth和nHeight說明了目的矩形及源位圖的寬和高。pSrcDC指向源設備上下文,xSrc和ySrc說明了源矩形相對于源位圖左上角的偏移。參數dwRop指定了光柵操作(ROP)代碼,一些常用的ROP代碼如表11.2所示。

     

    表11.2 常用的ROP代碼

     

    ROP碼

     

    含義

     

    BLACKNESS

     

    輸出黑色

     

    DSTINVERT

     

    反轉目的位圖

     

    MERGECOPY

     

    用與操作把圖案(Pattern)與源位圖融合起來

     

    MERGEPAINT

     

    用或操作把反轉的源位圖與目的位圖融合起來

     

    NOTSRCCOPY

     

    把源位圖反轉然后拷貝到目的地

     

    NOTSRCERASE

     

    用或操作融合源和目的位圖,然后再反轉

     

    PATCOPY

     

    把圖案拷貝到目的位圖中

     

    PATINVERT

     

    用異或操作把圖案與目的位圖相融合

     

    PATPAINT

     

    用或操作融合圖案和反轉的源位圖,然后用或操作把結果與目的位圖融合

     

    SRCAND

     

    用與操作融合源位圖和目的位圖

     

    SRCCOPY

     

    把源位圖拷貝到目的位圖

     

    SRCERASE

     

    先反轉目的位圖,再用與操作將其與源位圖融合

     

    SRCINVERT

     

    用異或操作融合源位圖和目的位圖

     

    SRCPAINT

     

    用或操作融合源位圖和目的位圖

     

    WHITENESS

     

    輸出白色

     

     

    函數CDC::StretchBlt的聲明為:

     

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

     

     

      該函數把位圖從源矩形拷貝到目的矩形中,如果源和目的矩形尺寸不同,那么將縮放位圖的功能以適應目的矩形的大小。函數的大部分參數與BitBlt的相同,但多了兩個參數nSrcWidth和nSrcHeight用來指定源矩形的寬和高。

      DDB的一個重要用途是用作設備上下文的顯示表面。每一個設備上下文都包含有一個DDB,該位圖實際上是在顯示設備的緩沖區中(如視頻內存),我們可以把它看做設備上下文的顯示表面,設備上下文用GDI函數繪圖實際上就是修改它所包含的DDB(顯示表面)的過程。

      普通的設備上下文都是在屏幕上繪圖的,而使用內存設備上下文則可以在系統內存中繪制圖形。內存設備上下文是一種特殊的設備上下文,它將系統內存用作顯示表面。程序可以使用內存設備上下文預先在系統內存中繪制復雜的圖形,然后再快速地將其復制到實際的設備上下文的顯示表面上,而繪制圖形的結果仍保存在內存設備上下文的DDB中。

    提示:有人可能會想到用BitBlt函數把繪圖結果從顯示設備拷貝到內存設備上下文中,這種方法可以工作,但有時會出錯。當源矩形被別的窗口遮住時,BitBlt會把別的窗口中的像素拷貝下來。

      內存設備上下文缺省的DDB是一個1×1的單色位圖,如此小的顯示表面顯然是沒有用的,因此程序一般要為內存設備對象選擇一個合適大小的彩色DDB。

    下面這段代碼創建了一個內存設備上下文,并在其包含的DDB中畫了一個灰色實心矩形,然后再把DDB輸出到屏幕上。

     

    void CMyView::OnDraw(CDC* pDC)

    {

    . . .

    CDC MemDC;

    CBitmap bm,*oldBmp;

    MemDC.CreateCompatibleDC(pDC); //創建一個兼容的內存設備上下文

    bm.CreateCompatibleBitmap(pDC,100,50); //創建一個兼容的DDB

    oldBmp=MemDC.SelectObject(&bm);

    MemDC.SelectStockObject(BLACK_PEN);

    MemDC.SelectStockObject(GRAY_BRUSH);

    MemDC.Rectangle(0,0,50,50); //在DDB中畫一個矩形

    pDC->BitBlt(0,0,100,50,&MemDC,0,0,SRCCOPY);

    MemDC.SelectObject(oldBmp); //使位圖bm對象脫離設備上下文

    . . .

    }

     

      在上面的代碼中,繪圖的結果保存在位圖bm中,一旦調用MemDC.SelectObject(oldBmp)使位圖bm脫離設備上下文,該位圖就可以被其它對象使用。

    下面是別人的一段代碼,我無法理解CreateCompatibleBitmap函數的意義。兼容位圖到里是做什么的?不明白!

    CPaintDC dc(this); // 用于繪制的設備上下文

    CRect rcClient; 
    GetClientRect(&rcClient);

    //構造內存DC,用于畫圖 
    CDC m_MemDC; 
    m_MemDC.CreateCompatibleDC(&dc);

    CBitmap btScreen; 
    btScreen.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height());

    m_MemDC.SelectObject(&btScreen); 
    btScreen.DeleteObject();

    //這里畫圖 
    ...

    dc.BitBlt(rcClient.left, rcClient.top, rcClient.Width(), rcClient.Height(), &m_MemDC, 0, 0, SRCCOPY);

    m_MemDC.DeleteDC();

    ///////////////////////////////////////////// 
    一) 
    在上面代碼中,如果我將 
    btScreen.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height()); 
    換成 
    btScreen.LoadBitmap(IDB_BITMAP1); 
    能達到同樣的效果嗎?

    二) 
    btScreen.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height()); 
    m_MemDC.SelectObject(&btScreen); 
    CreateCompatibleBitmap創建一幅兼容位圖后將該容易位圖選入DC中,這個兼容位圖到里是個什么圖片?我發現,將該語句屏蔽后,程序運行后顯示有些地方是黑的。不知道為什么。

    三) 
    我想知道,CreateCompatibleBitmap到里創建了一幅什么位圖啊?這個函數里面根本就沒有填入任何位圖信息嘛,難道它創建的是一幅空位圖嗎?它有什么意思啊?平常都是用LoadBitmap來創建位圖的,真不知道什么時候該用CreateCompatibleBitmap函數,對這個函數一點都不理解,希望有高手能詳細指點一下,重分答謝!
    網友回復:記不清楚了,大概是每個新建的內存兼容DC里選中的位圖都是1*1的灰度圖,不創建一個兼容位圖選進去的話,現實意義上說這個DC不可用(往上面bitblt)
    網友回復:兼容位圖是位圖的各種信息與設備相兼容,主要是顏色位數要相同。 
    新創建的位圖所有像素值都是0,通常是黑色。 
    兼容位圖主要用于與設備相互復制圖象,最常見的就是“雙緩沖”繪圖方式。
    網友回復:CreateCompatibleBitmap用法

    創建一幅與設備有關位圖,它與指定的設備場景兼容

    內存設備場景即與彩色位圖兼容,也與單色位圖兼容。這個函數的作用是創建一幅與當前選入hdc中的場景兼容。對一個內存場景來說,默認的位圖是單色的。倘若內存設備場景有一個DIBSection選入其中,這個函數就會返回DIBSection的一個句柄。如hdc是一幅設備位圖,那么結果生成的位圖就肯定兼容于設備(也就是說,彩色設備生成的肯定是彩色位圖) 
    如果nWidth和nHeight為零,返回的位圖就是一個1×1的單色位圖 
    一旦位圖不再需要,一定用DeleteObject函數釋放它占用的內存及資源

    網友回復:一:可以,但是要注意位圖的大小。 
    二:內存DC默認的位圖是1x1單色位圖,必須選入屏幕兼容的位圖(也可以是其它格式)才能繪制、顯示對應格式的顏色; 
    三:CreateCompatibleBitmap創建的位圖是空的,一般初始化為黑色(和操作系統有關),關鍵是復制了參數中dc的位圖格式。

    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全