古詩詞大全網 - 成語故事 - 求用C++做的圖像融合代碼 謝謝各位大俠了

求用C++做的圖像融合代碼 謝謝各位大俠了

遊戲,無非就是由核心操作和界面組成。界面壹般都有前景背景,背景壹般是顯示壹張大的位圖,前景壹般是被人操作(或計算機模擬人操作)的那部分。背景位圖壹般都是覆蓋了整個界面,它周圍整潔,只要妳把它畫好了,加上去就行;而前景位圖不同,它壹般是不規矩的,如飛機、動物、人物等。而像上例,獅子位圖的周圍是原位圖的顏色,而不是背景的顏色,不好看。

那麽,怎樣把前景位圖的背景顏色去掉,而使背景位圖能看到呢?就是本節的內容。實現的原理是:指定壹種顏色,然後對這種顏色進行處理,使它的色素不畫出來。如上面的獅子,指定白色RGB(255,255,255)為透明色,就行了。

下面就介紹壹個函數TransparentBitmap():

//本函數把壹種指定的顏色變成透明色,並可改變大小

// hdc 顯示句柄

// hBitmap要顯示的位圖

// xStart,xStart顯示的位置

// xadd,yadd顯示的位圖的大小變化:放大縮小

// 如:xadd=3表示位圖寬度加3

// cTransparentColor變成透明的那種顏色

void CMy1_6View::TransparentBitmap(HDC hdc, HBITMAP hBitmap,short xStart,

short yStart, short xadd,short yadd, COLORREF cTransparentColor)

{

BITMAP m_bm;

COLORREF cColor;

// 創建臨時DC

HDC hMem, hBack, hObject, hTemp, hSave;

hBack = CreateCompatibleDC(hdc);

hObject = CreateCompatibleDC(hdc);

hMem = CreateCompatibleDC(hdc);

hSave = CreateCompatibleDC(hdc);

hTemp = CreateCompatibleDC(hdc);

// 選入位圖

SelectObject(hTemp, hBitmap);

GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&m_bm);

//顯示位圖寬高

POINT ptSize;

// 取得位圖的寬度

ptSize.x = m_bm.bmWidth;

// 取得位圖的該度

ptSize.y = m_bm.bmHeight;

// 轉換為邏輯點值

DPtoLP(hTemp, &ptSize, 1);

// 創建臨時位圖

HBITMAP bmBack, bmObject, bmMem, bmSave;

// 單色位圖

bmBack = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);

bmObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);

// 與設備兼容位圖

bmMem = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);

bmSave = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);

// 將創建的臨時位圖選入臨時DC中

HBITMAP OldbmBack, OldbmObject, OldbmMem, OldbmSave;

OldbmBack = (HBITMAP)SelectObject(hBack, bmBack);

OldbmObject = (HBITMAP)SelectObject(hObject, bmObject);

OldbmMem = (HBITMAP)SelectObject(hMem, bmMem);

OldbmSave = (HBITMAP)SelectObject(hSave, bmSave);

// 設置映射模式

SetMapMode(hTemp, GetMapMode(hdc));

// 先保留原始位圖

BitBlt(hSave, 0, 0, ptSize.x, ptSize.y, hTemp, 0, 0, SRCCOPY);

// 將背景顏色設置為需透明的顏色

cColor = SetBkColor(hTemp, cTransparentColor);

// 創建目標屏蔽碼

BitBlt(hObject, 0, 0, ptSize.x, ptSize.y, hTemp, 0, 0, SRCCOPY);

// 恢復源DC的原始背景色

SetBkColor(hTemp, cColor);

// 創建反轉的目標屏蔽碼

BitBlt(hBack, 0, 0, ptSize.x, ptSize.y, hObject, 0, 0, NOTSRCCOPY);

// 拷貝主DC的背景到目標DC

BitBlt(hMem, 0, 0, ptSize.x, ptSize.y, hdc, xStart, yStart, SRCCOPY);

// 屏蔽位圖的顯示區

BitBlt(hMem, 0, 0, ptSize.x, ptSize.y, hObject, 0, 0, SRCAND);

// 屏蔽位圖中的透明色

BitBlt(hTemp, 0, 0, ptSize.x, ptSize.y, hBack, 0, 0, SRCAND);

// 將位圖與目標DC的背景左異或操作

BitBlt(hMem, 0, 0, ptSize.x, ptSize.y, hTemp, 0, 0, SRCPAINT);

// 拷貝目標到屏幕上

StretchBlt(hdc, xStart, yStart, ptSize.x+xadd, ptSize.y+yadd, hMem, 0, 0, ptSize.x, ptSize.y,SRCCOPY);

// 恢復原始位圖

BitBlt(hTemp, 0, 0, ptSize.x, ptSize.y, hSave, 0, 0, SRCCOPY);

// 刪除臨時內存位圖

DeleteObject(SelectObject(hBack, OldbmBack));

DeleteObject(SelectObject(hObject, OldbmObject));

DeleteObject(SelectObject(hMem, OldbmMem));

DeleteObject(SelectObject(hSave, OldbmSave));

// 刪除臨時內存DC

DeleteDC(hMem);

DeleteDC(hBack);

DeleteDC(hObject);

DeleteDC(hSave);

DeleteDC(hTemp);

}

註釋已經寫得很清楚了,用時只要按照要求在函數括號裏加上各個值就行了。下面用實例1_6演示壹下:

a. 新建單文檔工程1_6,加上變量如下:(註釋已在上面)

short xStart;

short yStart;

short xadd;

short yadd;

CBitmap m_Bitmap;

COLORREF cTransparentColor;

b. 在函數CMy1_6View()加上以下語句:

CMy1_6View::CMy1_6View()

{

// TODO: add construction code here

xStart=30;

yStart=30;

xadd=0;

yadd=0;

m_Bitmap.LoadBitmap(IDB_BITMAP1);

cTransparentColor=RGB(255,255,255);

}

c. 添加上面的獅子位圖。

d. 加上OnCreate(LPCREATESTRUCT lpCreateStruct)和OnTimer(UINT nIDEvent)函數如下:

int CMy1_6View::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

if (CView::OnCreate(lpCreateStruct) == -1)

return -1;

// TODO: Add your specialized creation code here

SetTimer(1,150,NULL);

return 0;

}

void CMy1_6View::OnTimer(UINT nIDEvent)

{

// TODO: Add your message handler code here and/or call default

//獲取指針pdc

CDC *pDC=GetDC();

//調用OnDraw(pDC)重畫

OnDraw(pDC);

CClientDC dc(this);

//向右向下移動

xStart+=5;

yStart+=5;

//位圖寬高加2

xadd+=2;

yadd+=2;

//顯示

TransparentBitmap(dc.GetSafeHdc(), m_Bitmap, xStart, yStart, xadd,yadd, cTransparentColor);

CView::OnTimer(nIDEvent);

}

e. 上面的“透明位圖”函數還沒有定義,必須把開頭的函數添加進來。把函數整個拷貝到1_6View.cpp,然後在1_6View.h中加上:

void TransparentBitmap(HDC hdc, HBITMAP hBitmap, short xStart,

short yStart, short xadd,short yadd, COLORREF cTransparentColor);

f. 最後,在函數OnDraw(CDC* pDC)加上背景:

void CMy1_6View::OnDraw(CDC* pDC)

{

CMy1_6Doc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

// TODO: add draw code for native data here

//畫紅色背景

CBrush mybrush1;

mybrush1.CreateSolidBrush(RGB(255,0,0));

CRect myrect1(0,0,1200,800);

pDC->FillRect(myrect1,&mybrush1);

}

g. 運行,怎麽樣?圖象還會變大呢!