• <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>

            KISS(Keep It Simple, Standard)

              C++博客 :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
              10 Posts :: 0 Stories :: 24 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(10)

            我參與的團隊

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

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

            一、TransparentBlt 函數(shù)的使用

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

            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);
            
            二、實現(xiàn)TransparentBlt函數(shù)

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

            實驗素材:有兩張位圖:bk.bmp是背景位圖,football.bmp包含透明區(qū)域,透明色為藍色RGB(0,0,0xff)
            實驗?zāi)康模阂詁k.bmp為背景,將football.bmp繪制到背景中,形成如下的最終效果圖。

             



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

            2.1.1 生成足球的單色掩碼位圖,透明區(qū)域為白色(全1),非透明區(qū)域為黑色(全0)
            HBITMAP hMaskBMP = CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL); // 建立單色位圖
            SetBkColor(hImageDC, RGB(0,0,0xff)); // 設(shè)置背景色為藍色
            BitBlt(hMaskDC, 0, 0, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCCOPY); // 拷貝到hMaskDC
            這樣足球位圖中藍色區(qū)域在掩碼位圖中成了白色,其它區(qū)域為黑色,此時hMaskBMP 如下圖:
            (圖一)

            2.1.2 設(shè)置背景色為黑色,前景色為白色,將掩碼位圖(圖一)與足球位圖相"與"
            SetBkColor(hImageDC, RGB(0,0,0));
            SetTextColor(hImageDC, RGB(255,255,255));
            BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);
            
            這樣,掩碼位圖中背景色(黑色)的區(qū)域在hImageBMP中被保留,前景色(白色)的部分變?yōu)楹谏?此時hImageBMP 如下圖:
            (圖二)

            2.1.3 設(shè)置背景色為白色,前景色為黑色,將掩碼位圖(圖一)與背景進行“與”運算
            SetBkColor(hdcDest,RGB(255,255,255));
            SetTextColor(hdcDest,RGB(0,0,0));
            BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);
            掩碼中白色區(qū)域(數(shù)據(jù)與1相“與”結(jié)果不變)使背景保持不變,黑色區(qū)域變成黑色,此時背景顯示如下:
            (圖三)

            2.1.4 將hImageBMP(圖二)與背景(圖三)進行“或”運算
            BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCPAINT);
            這樣就將足球繪制到背景上了。

            2.2 TransparentBlt2函數(shù)全部實現(xiàn)代碼
            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);	// 創(chuàng)建兼容位圖
            HBITMAP hOldMaskBMP, hMaskBMP = CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL);			// 創(chuàng)建單色掩碼位圖
            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);
            // 設(shè)置透明色
            SetBkColor(hImageDC, crTransparent);
            // 生成透明區(qū)域為白色,其它區(qū)域為黑色的掩碼位圖
            BitBlt(hMaskDC, 0, 0, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCCOPY);
            // 生成透明區(qū)域為黑色,其它區(qū)域保持不變的位圖
            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);
            // 清理、恢復(fù)
            SelectObject(hImageDC, hOldImageBMP);
            DeleteDC(hImageDC);
            SelectObject(hMaskDC, hOldMaskBMP);
            DeleteDC(hMaskDC);
            DeleteObject(hImageBMP);
            DeleteObject(hMaskBMP);
            }
            2.3 TransparentBlt的另外一個版本:TransparentBltU

            TransparentBltU是Christian Graus 在WinDEV發(fā)表的一個函數(shù),功能與TransparentBlt一致,以下是全部實現(xiàn)代碼:
            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函數(shù)旨在說明透明位圖的顯示原理,在Windows2000以上環(huán)境實際運用中建議使用現(xiàn)成的TransparentBlt函數(shù)來繪制透明位圖。
            posted on 2007-08-30 16:52 QUIRE-0216 閱讀(923) 評論(1)  編輯 收藏 引用 所屬分類: MFC

            Feedback

            # re: 透明位圖的顯示(轉(zhuǎn)) 2007-09-02 13:42 螞蟻終結(jié)者
            不錯,記得前不久還遇到過處理透明位圖的問題。不過當時還不知道
            TransparentBlt,是自己另做的掩碼位圖  回復(fù)  更多評論
              

            欧美激情精品久久久久| 精品久久久久久无码人妻热| 精品一二三区久久aaa片| 国内精品综合久久久40p| 无码人妻少妇久久中文字幕蜜桃| 99久久人妻无码精品系列| 国产99久久久国产精免费| 欧美伊人久久大香线蕉综合| 久久精品中文无码资源站| 久久久这里有精品中文字幕| 久久久久久曰本AV免费免费| 久久香蕉国产线看观看99| 久久天天躁夜夜躁狠狠| 青草影院天堂男人久久| 久久亚洲精品中文字幕| 久久精品无码免费不卡| 狠狠综合久久综合88亚洲| 国内精品伊人久久久久网站| 色狠狠久久AV五月综合| 久久夜色精品国产www| …久久精品99久久香蕉国产| 久久亚洲国产精品成人AV秋霞| 99久久成人18免费网站| 97久久精品国产精品青草| 一本色综合网久久| 亚洲人成无码网站久久99热国产 | 久久人妻少妇嫩草AV蜜桃| 久久伊人精品青青草原高清| 亚洲va中文字幕无码久久| 深夜久久AAAAA级毛片免费看| 久久精品国产久精国产| 国产成人精品久久一区二区三区| 久久久久久曰本AV免费免费| 久久只有这里有精品4| 无码乱码观看精品久久| 色综合合久久天天给综看| 中文字幕无码av激情不卡久久| 国产AⅤ精品一区二区三区久久| 99久久精品免费看国产一区二区三区| 996久久国产精品线观看| 青青草国产精品久久|