起因:我也是VC知識庫網站受益人,昨天開始調試《多層圖像合成》的例子,因為沒有找到源碼,而文中的代碼有點不全和錯誤,費了好多時間才調試出來,覺得本例子對圖象處理很有借鑒之處,現拿出來供大家參考以下,在此向原作者致謝,以下大部分是原作者文章的摘錄,我僅做了少量修改。
關鍵字:圖像合成
相關背景:多層圖像的合成在實際開發中具有非常廣泛的應用。首先兩個設備DC分別裝入了前景圖和背景圖,然後另一個DC載入一幅二值圖像,作為mask圖。將載入了前景圖的設備環境m_dcFore的背景色設為前景圖的背景色,將m_dcFore拷貝到載入了mask圖的設備環境maskDc,得到一個新的mask圖。新mask圖就是前景圖中背景色的地方轉為白色,其他轉為黑色的一幅圖。在將前景圖拷貝到mask圖的過程中,系統首先將前景圖轉換為單色圖。當位圖在彩色與單色之間轉換時,系統會使用設備的背景色,與背景色相同的地方轉換為白色,其他的轉換為黑色。設m_dcFore的前景色為白色,背景色為黑色,m_dcFore與maskDc做‘與’運算,得到新的前景圖。在做‘與’運算時,系統先將單色圖轉換為彩色圖,並用彩色圖的前景色和背景色作為轉換後的顏色。所以,新的前景圖的背景色轉變為黑色,其他的保持不變。設背景圖的前景色為黑色,背景色為白色,載入了背景圖的設備環境m_dcBk與maskDc做‘與’運算,得到新的背景圖。新的背景圖的前景色轉變為黑色,其他的保持不變。將新的背景圖與新的前景圖做‘或’運算,得到的新圖保持了背景圖的背景,更融合前景圖的前景,達到了我們想要的理想效果。
實現環境:Visual C++ 6.0
實現過程:
首先創建一個單文檔或多文檔的工程取名為CTestSelDrawPicApp。
在Resources中引入我們要合成的兩幅Bmp圖像(一幅作為背景圖、另一幅為前景圖),分別命名為IDB_BK、IDB_FORE。
給CCTestSelDrawPicView類建兩個CBitmap類型的成員變量,分別命名為m_bmpBk、m_bmpFore。
在CCTestSelDrawPicView類中新建兩個CDC類型的成員變量,分別命名為m_dcBk、m_dcFore。
在初始化函數中將兩幅Bmp圖像裝入。在CCTestSelDrawPicView::OnInitialUpdate()函數中加入如下代碼:
m_bmpBk.LoadBitmap(IDB_BK); //將背景圖載入
m_bmpFore.LoadBitmap(IDB_FORE); //將前景圖載入
CClientDC dc(this); //獲得當前客戶區設備環境
m_dcBk.CreateCompatibleDC(&dc); //創建與當前設備相兼容的設備
m_dcFore.CreateCompatibleDC(&dc);在CPicView類的OnDraw(CDC* pDC)函數中加入如下代碼: CBitmap* poldBk=m_dcBk.SelectObject(&m_bmpBk); //選入背景圖
CBitmap* poldFore=m_dcFore.SelectObject(&m_bmpFore);
CRect rect;
GetClientRect(&rect); //得到客戶區矩形
CDC maskDc; //創建設備環境maskDc
CBitmap maskBitmap;
maskDc.CreateCompatibleDC(pDC); //創建與當前設備相兼容的設備
maskBitmap.CreateBitmap(rect.Width(),rect.Height(),1,1,NULL ); //創建一個單色圖
CBitmap* pOldMaskDCBitmap = maskDc.SelectObject( &maskBitmap ); //選入單色圖
CBrush brush(RGB(255,255,255));
CBrush * oldbrush;
oldbrush=maskDc.SelectObject(&brush);
maskDc.FillRect(&rect,&brush);
//取得要消除的背景色值
COLORREF clrTrans= m_dcFore.GetPixel(2, 2);
// 設置前景圖的背景色
COLORREF clrSaveBk = m_dcFore.SetBkColor(clrTrans);
//將前景圖拷貝到maskDc
maskDc.BitBlt(0,0,rect.Width(),rect.Height(), &m_dcFore, 0,0,SRCCOPY);
//將前景圖拷貝到maskDc,此時maskDc如下圖:
//前景圖與mask做 ‘與’運算
m_dcFore.SetBkColor(RGB(0,0,0));
m_dcFore.SetTextColor(RGB(255,255,255));
m_dcFore.BitBlt(0,0,rect.Width(), rect.Height(),&maskDc,0,0,SRCAND);
//背景圖與mask做‘與’運算
m_dcBk.SetBkColor(RGB(255,255,255));
m_dcBk.SetTextColor(RGB(0,0,0));
m_dcBk.BitBlt(0,0,rect.Width(),rect.Height(),&maskDc,0,0,SRCAND);
//背景圖與前景圖做‘或’運算
m_dcBk.BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&m_dcFore,0,0,SRCPAINT);
//將合成後的圖像顯示
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&m_dcBk,0,0,SRCCOPY);
pDC->SelectObject(oldbrush);
m_bmpBk.SelectObject(poldBk);
m_bmpFore.SelectObject(poldFore);
全文完
本文配套源碼