1. 程式人生 > >透明點陣圖的顯示(TransparentBlt函式)

透明點陣圖的顯示(TransparentBlt函式)

包含透明色的點陣圖的繪製方法有多種,最簡單的方法是呼叫現成的函式: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

TransparentBltU是Christian 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函式來繪製透明點陣圖。

原始碼下載!

本文轉自:http://www.cnblogs.com/syxchina/archive/2010/06/01/2197688.html

相關推薦

MFC透明點陣顯示函式

研究好久才弄好,註釋的比較詳細,不明白的函式可以參考MSDN   bool TransparentDIB(CBitmap * dib, /*要繪製的點陣圖*/ CDC * pDC, /*目標DC*/ CRect * rct, /*目標矩形*/ C

透明點陣顯示(TransparentBlt函式)

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

6.VC(ui)-MFC下實現透明點陣

 我們在進行程式的介面設計時,常常希望將點陣圖的前景顯示在介面上,而將點陣圖的背景隱藏起來,將點陣圖與介面很自然的融合在一起,本文介紹了透明點陣圖的製作知識,並將透明點陣圖在一個對話方塊中顯示了出來。 直接上圖:原圖:Demo效果圖: 步驟如下:   1、設定待顯示點陣圖的

MFC中實現簡單的點陣顯示、處理

最近在做影象採集的工作,需要處理影象資料,所以學習了一下點陣圖顯示,而且只看了裝置相關點陣圖DDB。基本上實現了點陣圖的顯示、點陣圖資料的處理等功能。這裡就記錄一下我自己的理解,不一定全都對,僅供參考而已。 要顯示點陣圖,需要做如下工作: CStatic* pStati

透明點陣Ron Gery Microsoft 網路開發技術小組

摘要 這篇文章討論了在 Microsoft Windows 圖形環境中用點陣圖達到透明和遮蔽效果的幾種方法,包括通過模擬和使用特殊的驅動器功能。包含其中的一個小樣本應用程式 TRANSBLT 詳細闡明瞭這篇文章討論的大多數方法。 介紹 使用透明(TRANSPARENT)背景

使用gdal讀取影象資料,然後用構建gdi+點陣顯示

如果想利用雙快取顯示gdal讀取的影象資料,把影象資料構建成一個gdi+的點陣圖來顯示void CGdalGdiView::OnDraw(CDC* /*pDC*/) { CGdalGdiDoc* pDoc = GetDocument(); ASSERT_VALID(pD

MFC點陣顯示

   這是一種簡單的方式,分為四個步驟. 1.建立點陣圖,這裡的點陣圖僅限bmp格式的. CBitmap bitmap; bitmap.LoadBitmapA(IDB_BITMAP1); 匯入點陣圖資源 2.建立相容DC, CDC dcCompatible;

建立透明點陣的方法

在做介面開發的時候經常需要去建立透明的點陣圖,由於MFC沒有封裝這樣的函式,經過多方查詢資料和試驗,終於寫出了一個可以建立透明點陣圖的函式,下面給大家分享一下。void BitTrans(int nXDest, // 目標起點X         int nYDest,//

MFC基於對話方塊如何新增點陣並使點陣背景透明TransparentBlt函式

MFC中比較重要的一部分學習內容即是繪圖,而繪圖時我們會發現如果想插入一張圖片而又不想要圖片的背景,或者已經把圖片的背景用Ps去掉了,但是在MFC視窗中顯示圖片的時候又有了白色的背景,這個時候就可以使用TransparentBlt函式(通常支援點陣圖)來實現將圖

MFC中實現點陣透明顯示

好久沒寫部落格了,嘗試著重新開張~ 最近在協助同事修改原有的一個程式,因為要申請個什麼東西,介面上也一直在下功夫。 原來的程式介面是用MFC做的,想新增一些圖片,不過圖片都不是矩形,周圍有白邊,為此,想將這些白邊做透明處理。遍尋網上解決方案,有所獲,如下: 我們在

VC對話方塊如何新增WM_ERASEBKGND訊息(OnEraseBkgnd函式)及對話方塊使用點陣背景並透明

1、使用OnEraseBkgnd函式實現對話方塊點陣圖背景 BOOL CDisplayBmpBackGroundDlg::OnEraseBkgnd(CDC   *pDC)   //老婆:增加擦出背景函式{ CRect rect; GetClientRect(&rect);  CBitmap m_p

VC對話方塊使用OnEraseBkgnd函式點陣背景並透明

1、使用OnEraseBkgnd函式實現對話方塊點陣圖背景 BOOL CDisplayBmpBackGroundDlg::OnEraseBkgnd(CDC   *pDC)   //增加擦除背景函式 {  CRect rect;  GetClientRect(&re

基於VC6.0的控制檯作圖--顯示點陣(bmp)

文章目錄 GDI是什麼? 用`LoadImage`讀取點陣圖bmp檔案 將點陣圖選入記憶體相容區 將記憶體相容區拷貝到螢幕區 恢復現場 銷燬臨時的記憶體DC 例項 ( showbmp.cpp) 進一步的改

QT QCharts QScatterSeries 空心點陣,滑鼠移動到上面顯示數值,滑鼠移開數值消失

在最近接到的需求是這樣的,畫一個折線圖,關鍵點使用空心的圓點標識出來,滑鼠移動到關鍵點上,顯示出當前數值;滑鼠移走數值消失。 我們遇到這個需求的時候,第一時間就會想到使用 QLineSeries 畫折線圖。首先初始化 QChart *chart = new Q

【遊戲程式設計】顯示點陣

執行結果: 原始碼: #include <windows.h> #pragma comment(lib, "winmm.lib") //呼叫PlaySound函式所需庫檔案t #define WINDOW_WIDTH 600 #defin

VC用ADO存取顯示jpg/bmp點陣檔案

 週六和今天兩天的時間,把資料庫關於圖片的儲存和顯示 實現了,雖然時間有點長,但是還是實現了。以下是網上找到的資料,很有用。 第一步:首先是要開啟一個位圖檔案,這裡使用的控制元件用Picture控制元件,就是控制元件圖示右邊最上面那個,改ID號為IDC_PICTURE,然

VC++圖片控制元件(Picture Control)顯示資源點陣(BMP)、檔案點陣(BMP)、其它格式檔案圖片(JPG\PNG\BMP)的方法

在VC++ MFC程式設計中,我們常使用Picture Control圖片控制元件來顯示影象。下面簡單歸納幾種顯示不同的方式: 第一種、資源點陣圖方式顯示BMP圖片 如果要顯示的是一張BMP點陣圖,則可以採用資源點陣圖方式,具體步驟如下: (1)將BMP檔案拷貝到工程的r

VC下2、4、8、16、24、32位點陣的資料解析與顯示

在VC中,點陣圖顯示一般有現成的方式,如使用picture控制元件、GetDC()->StretchBlt、::BitBlt等,但這些方式都是高層的封裝,讓你不清楚一副點陣圖是如何解析並顯示到DC上的。實際應用中,比如影象處理,視訊顯示等,需要操作到點陣圖中的畫素,這

繪製透明背景點陣

一、繪製透明背景的點陣圖,windows提供了一個API函式 TransparentBlt The TransparentBlt function performs a bit-block transfer of the color data corresponding to a rectangle of p

MFC中在檢視視窗顯示點陣

本例將在單文件工程的檢視視窗中顯示一副點陣圖,視窗的左邊為原圖,右邊為放大後的點陣圖。 本例的demo如下: 首先    在資源檢視中插入一副點陣圖,然後在Ondraw函式中實在載入點陣圖和顯示 void CMFCApplication18View::OnDra