• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 224  文章 - 41  trackbacks - 0
            <2008年11月>
            2627282930311
            2345678
            9101112131415
            16171819202122
            23242526272829
            30123456

            享受編程

            常用鏈接

            留言簿(11)

            隨筆分類(159)

            隨筆檔案(224)

            文章分類(2)

            文章檔案(4)

            經典c++博客

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            原文地址:http://www.vckbase.com/document/viewdoc/?id=532

            包含透明色的位圖的繪制方法有多種,最簡單的方法是調用現成的函數:TransparentBlt,也可以通過自己的代碼實現類似TransparentBlt的功能,實現過程也有兩種形式,一種是事先做一張掩碼位圖,另一種是動態生成掩碼位圖。本文將介紹動態生成掩碼位圖繪制具有透明區域位圖的方法。

            一、TransparentBlt 函數的使用

            TransparentBlt 函數在Windows98/Windows2000以上版本運行,系統中需要包含 Msimg32.dll,使用時可以鏈接 Msimg32.lib
            Windows98下的TransparentBlt會產生資源泄漏,所以不建議在WIN98下使用該函數。
            TransparentBlt函數原型如下:

            BOOL TransparentBlt(

            HDC hdcDest,      // 目標DC

            int nXOriginDest,   // 目標X偏移

            int nYOriginDest,   // 目標Y偏移

            int nWidthDest,     // 目標寬度

            int hHeightDest,    // 目標高度

            HDC hdcSrc,         // DC

            int nXOriginSrc,    // X起點

            int nYOriginSrc,    // Y起點

            int nWidthSrc,      // 源寬度

            int nHeightSrc,     // 源高度

            UINT crTransparent  // 透明色,COLORREF類型

            );

            使用示例

            CBitmap FootballBMP;

            FootballBMP.LoadBitmap(IDB_FOOTBALLBMP);

            CDC ImageDC;

            ImageDC.CreateCompatibleDC(pDC);

            CBitmap *pOldImageBMP = ImageDC.SelectObject(&FootballBMP);

            TransparentBlt(pDC->m_hDC, 0, 0, 218, 199, ImageDC.m_hDC, 0, 0, 218, 199, RGB(0,0,0xff));

            ImageDC.SelectObject(pOldImageBMP);

            二、實現TransparentBlt函數

            為了理解具有透明色位圖的繪制過程,我們來親手建立一個具有同TransparentBlt功能一致的實驗函數,稱之為TransparentBlt2

            實驗素材:有兩張位圖:bk.bmp是背景位圖,football.bmp包含透明區域,透明色為藍色RGB(0,0,0xff)
            實驗目的:以bk.bmp為背景,將football.bmp繪制到背景中,形成如下的最終效果圖。
             

            2.1 透明位圖繪制原理
            假設football.bmp ->載入 HBITMAP hImageBMP -> 選入 HDC hImageDC

            2.1.1 生成足球的單色掩碼位圖,透明區域為白色(全1),非透明區域為黑色(全0) 

            HBITMAP hMaskBMP = CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL); // 建立單色位圖

            SetBkColor(hImageDC, RGB(0,0,0xff)); // 設置背景色為藍色

            BitBlt(hMaskDC, 0, 0, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCCOPY); // 拷貝到hMaskDC

            這樣足球位圖中藍色區域在掩碼位圖中成了白色,其它區域為黑色,此時hMaskBMP 如下圖:
             (圖一)

            2.1.2 設置背景色為黑色,前景色為白色,將掩碼位圖(圖一)與足球位圖相"" 

            SetBkColor(hImageDC, RGB(0,0,0));

            SetTextColor(hImageDC, RGB(255,255,255));

            BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);

            這樣,掩碼位圖中背景色(黑色)的區域在hImageBMP中被保留,前景色(白色)的部分變為黑色。 此時hImageBMP 如下圖:
             (圖二)

            2.1.3 設置背景色為白色,前景色為黑色,將掩碼位圖(圖一)與背景進行運算

            SetBkColor(hdcDest,RGB(255,255,255));

            SetTextColor(hdcDest,RGB(0,0,0));

            BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);

            掩碼中白色區域(數據與1結果不變)使背景保持不變,黑色區域變成黑色,此時背景顯示如下:
             (圖三)

            2.1.4 hImageBMP(圖二)與背景(圖三)進行運算 

            BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCPAINT);

            這樣就將足球繪制到背景上了。

            2.2 TransparentBlt2函數全部實現代碼

            void TransparentBlt2( HDC hdcDest,      // 目標DC

                                int nXOriginDest,   // 目標X偏移

                                int nYOriginDest,   // 目標Y偏移

                                int nWidthDest,     // 目標寬度

                                int nHeightDest,    // 目標高度

                                HDC hdcSrc,         // DC

                                int nXOriginSrc,    // X起點

                                int nYOriginSrc,    // Y起點

                                int nWidthSrc,      // 源寬度

                                int nHeightSrc,     // 源高度

                                UINT crTransparent  // 透明色,COLORREF類型

                                )

            {

                HBITMAP hOldImageBMP, hImageBMP = CreateCompatibleBitmap(hdcDest, nWidthDest, nHeightDest); // 創建兼容位圖

                HBITMAP hOldMaskBMP, hMaskBMP = CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL);          // 創建單色掩碼位圖

                HDC     hImageDC = CreateCompatibleDC(hdcDest);

                HDC     hMaskDC = CreateCompatibleDC(hdcDest);

                hOldImageBMP = (HBITMAP)SelectObject(hImageDC, hImageBMP);

                hOldMaskBMP = (HBITMAP)SelectObject(hMaskDC, hMaskBMP);

                // 將源DC中的位圖拷貝到臨時DC

                if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc)

                    BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY);

                else

                    StretchBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, 

                                hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);

                // 設置透明色

                SetBkColor(hImageDC, crTransparent);

                // 生成透明區域為白色,其它區域為黑色的掩碼位圖

                BitBlt(hMaskDC, 0, 0, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCCOPY);

                // 生成透明區域為黑色,其它區域保持不變的位圖

                SetBkColor(hImageDC, RGB(0,0,0));

                SetTextColor(hImageDC, RGB(255,255,255));

                BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);

                // 透明部分保持屏幕不變,其它部分變成黑色

                SetBkColor(hdcDest,RGB(255,255,255));

                SetTextColor(hdcDest,RGB(0,0,0));

                BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);

                // ""運算,生成最終效果

                BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCPAINT);

                // 清理、恢復    

                SelectObject(hImageDC, hOldImageBMP);

                DeleteDC(hImageDC);

                SelectObject(hMaskDC, hOldMaskBMP);

                DeleteDC(hMaskDC);

                DeleteObject(hImageBMP);

                DeleteObject(hMaskBMP);

            }

            2.3 TransparentBlt的另外一個版本:TransparentBltU

            TransparentBltUChristian Graus WinDEV發表的一個函數,功能與TransparentBlt一致,以下是全部實現代碼

            bool TransparentBltU(

                 HDC dcDest,         // handle to Dest DC

                 int nXOriginDest,   // x-coord of destination upper-left corner

                 int nYOriginDest,   // y-coord of destination upper-left corner

                 int nWidthDest,     // width of destination rectangle

                 int nHeightDest,    // height of destination rectangle

                 HDC dcSrc,          // handle to source DC

                 int nXOriginSrc,    // x-coord of source upper-left corner

                 int nYOriginSrc,    // y-coord of source upper-left corner

                 int nWidthSrc,      // width of source rectangle

                 int nHeightSrc,     // height of source rectangle

                 UINT crTransparent  // color to make transparent

              )

            {

                 if (nWidthDest < 1) return false;

                 if (nWidthSrc < 1) return false;

                 if (nHeightDest < 1) return false;

                 if (nHeightSrc < 1) return false;

                 HDC dc = CreateCompatibleDC(NULL);

                 HBITMAP bitmap = CreateBitmap(nWidthSrc, nHeightSrc, 1, GetDeviceCaps(dc,

                                                                          BITSPIXEL), NULL);

                 if (bitmap == NULL)

                 {

                     DeleteDC(dc);    

                     return false;

                 }

                 HBITMAP oldBitmap = (HBITMAP)SelectObject(dc, bitmap);

                 if (!BitBlt(dc, 0, 0, nWidthSrc, nHeightSrc, dcSrc, nXOriginSrc,

                                                                     nYOriginSrc, SRCCOPY))

                 {

                     SelectObject(dc, oldBitmap); 

                     DeleteObject(bitmap);        

                     DeleteDC(dc);                

                     return false;

                 }

                 HDC maskDC = CreateCompatibleDC(NULL);

                 HBITMAP maskBitmap = CreateBitmap(nWidthSrc, nHeightSrc, 1, 1, NULL);

                 if (maskBitmap == NULL)

                 {

                     SelectObject(dc, oldBitmap); 

                     DeleteObject(bitmap);        

                     DeleteDC(dc);                

                     DeleteDC(maskDC);            

                     return false;

                 }

                 HBITMAP oldMask =  (HBITMAP)SelectObject(maskDC, maskBitmap);

                 SetBkColor(maskDC, RGB(0,0,0));

                 SetTextColor(maskDC, RGB(255,255,255));

                 if (!BitBlt(maskDC, 0,0,nWidthSrc,nHeightSrc,NULL,0,0,BLACKNESS))

                 {

                     SelectObject(maskDC, oldMask); 

                     DeleteObject(maskBitmap);      

                     DeleteDC(maskDC);              

                     SelectObject(dc, oldBitmap);   

                     DeleteObject(bitmap);          

                     DeleteDC(dc);                  

                     return false;

                 }

                 SetBkColor(dc, crTransparent);

                 BitBlt(maskDC, 0,0,nWidthSrc,nHeightSrc,dc,0,0,SRCINVERT);

                 SetBkColor(dc, RGB(0,0,0));

                 SetTextColor(dc, RGB(255,255,255));

                 BitBlt(dc, 0,0,nWidthSrc,nHeightSrc,maskDC,0,0,SRCAND);

                 HDC newMaskDC = CreateCompatibleDC(NULL);

                 HBITMAP newMask;

                 newMask = CreateBitmap(nWidthDest, nHeightDest, 1,

                                                GetDeviceCaps(newMaskDC, BITSPIXEL), NULL);

                 if (newMask == NULL)

                 {

                     SelectObject(dc, oldBitmap);

                     DeleteDC(dc);

                     SelectObject(maskDC, oldMask);

                     DeleteDC(maskDC);

                      DeleteDC(newMaskDC);

                     DeleteObject(bitmap);     

                     DeleteObject(maskBitmap); 

                     return false;

                 }

                 SetStretchBltMode(newMaskDC, COLORONCOLOR);

                 HBITMAP oldNewMask = (HBITMAP) SelectObject(newMaskDC, newMask);

                 StretchBlt(newMaskDC, 0, 0, nWidthDest, nHeightDest, maskDC, 0, 0,

                                                           nWidthSrc, nHeightSrc, SRCCOPY);

                 SelectObject(maskDC, oldMask);

                 DeleteDC(maskDC);

                 DeleteObject(maskBitmap); 

                 HDC newImageDC = CreateCompatibleDC(NULL);

                 HBITMAP newImage = CreateBitmap(nWidthDest, nHeightDest, 1,

                                                GetDeviceCaps(newMaskDC, BITSPIXEL), NULL);

                 if (newImage == NULL)

                 {

                     SelectObject(dc, oldBitmap);

                     DeleteDC(dc);

                     DeleteDC(newMaskDC);

                     DeleteObject(bitmap);     

                     return false;

                 }

                 HBITMAP oldNewImage = (HBITMAP)SelectObject(newImageDC, newImage);

                 StretchBlt(newImageDC, 0, 0, nWidthDest, nHeightDest, dc, 0, 0, nWidthSrc,

                                                                      nHeightSrc, SRCCOPY);

                 SelectObject(dc, oldBitmap);

                 DeleteDC(dc);

                 DeleteObject(bitmap);     

                 BitBlt( dcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,

                                                                  newMaskDC, 0, 0, SRCAND);

                 BitBlt( dcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,

                                                               newImageDC, 0, 0, SRCPAINT);

                 SelectObject(newImageDC, oldNewImage);

                 DeleteDC(newImageDC);

                 SelectObject(newMaskDC, oldNewMask);

                 DeleteDC(newMaskDC);

                 DeleteObject(newImage);   

                 DeleteObject(newMask);    

                 return true;

            }


            說明:本文提供的TransparentBlt2函數旨在說明透明位圖的顯示原理,在Windows2000以上環境實際運用中建議使用現成的TransparentBlt函數來繪制透明位圖。

            posted on 2010-03-18 15:18 漂漂 閱讀(448) 評論(0)  編輯 收藏 引用 所屬分類: 深入vc++
            亚洲AⅤ优女AV综合久久久| 久久精品国产亚洲av高清漫画 | 狠狠色综合网站久久久久久久 | 亚洲αv久久久噜噜噜噜噜| 青青热久久国产久精品| 日日狠狠久久偷偷色综合96蜜桃| 国产A级毛片久久久精品毛片| 一本大道加勒比久久综合| 久久精品草草草| 色综合久久天天综合| 99久久精品日本一区二区免费| 99久久精品午夜一区二区| 国产精品久久久久9999高清| 好属妞这里只有精品久久| 久久亚洲精品视频| 日韩亚洲国产综合久久久| 综合久久一区二区三区 | 中文精品99久久国产| 精品久久久无码人妻中文字幕 | 亚洲国产一成久久精品国产成人综合 | 狠狠色狠狠色综合久久| 久久香蕉国产线看观看乱码| 国产日产久久高清欧美一区| 精品久久人人爽天天玩人人妻| 久久亚洲天堂| 麻豆亚洲AV永久无码精品久久| 久久精品国产秦先生| 久久综合五月丁香久久激情| 国产成人久久精品一区二区三区 | 久久伊人亚洲AV无码网站| 久久国语露脸国产精品电影| 日本福利片国产午夜久久| 亚洲国产精品综合久久一线 | 久久国产午夜精品一区二区三区| 青春久久| 一本一道久久精品综合| 超级碰碰碰碰97久久久久| 久久综合久久综合久久| 久久人人爽人人爽人人av东京热| 国产精品成人无码久久久久久| 久久精品人人做人人爽电影 |