透明效果
創(chuàng)新互聯(lián)專注于大渡口網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠為您提供大渡口營銷型網(wǎng)站建設(shè),大渡口網(wǎng)站制作、大渡口網(wǎng)頁設(shè)計(jì)、大渡口網(wǎng)站官網(wǎng)定制、重慶小程序開發(fā)公司服務(wù),打造大渡口網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供大渡口網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。
由于所有的圖文件都是以矩形來儲(chǔ)存的,我們也許會(huì)需要把一張易拉罐圖片貼到窗口的背景圖上,而這種情況下如果直接進(jìn)行貼圖,結(jié)果如下圖:
這似乎不是我們想要的結(jié)果。
為了得到透明效果,我們需要運(yùn)用到BitBlt()貼圖函數(shù)以及其參數(shù)Raster的值來將圖片中不必要的部分去掉(又稱去背),使得圖中的主題可以與背景完美融合。
制作透明效果有很多種方法,但是基本上都是利用貼圖時(shí)不同的Raster運(yùn)算,通過轉(zhuǎn)換而產(chǎn)生相同的透明效果。在這里先來介紹一種透明運(yùn)算的方法。
我們以圖中的易拉罐為例子,首先準(zhǔn)備一張位圖,如下圖。
圖中的左邊的圖是要去背并貼到背景上的前景圖。右邊的黑白圖稱為“屏蔽圖”,在透明的過程中會(huì)用到它。要把去背的位圖與屏蔽圖合并成同一張圖,透明的時(shí)候再按照需要來進(jìn)行裁切??梢园阉殖蓛蓮垐D,但是這樣程序必須運(yùn)行兩次圖文件加載的操作。
有了屏蔽圖就可以利用貼圖函數(shù)來產(chǎn)生透明效果了,所需的貼圖步驟如下:
<1>將屏蔽圖與背景圖做"AND"運(yùn)算,Raster值為SRCAND,貼到目的地DC中。
<2>將前景圖與背景圖做"OR"運(yùn)算,Raster值為SRCPAINT,貼到目的地DC中。
為什么經(jīng)過上面兩個(gè)操作就能產(chǎn)生透明的效果呢?看下圖就理解了:
下面具體說明上面兩個(gè)步驟所產(chǎn)生的圖點(diǎn)色彩的變化。
1.屏蔽圖與背景圖做"AND"運(yùn)算
<1>屏蔽圖中的黑色部分與背景圖做"AND"運(yùn)算:
<2>屏蔽圖中的白色部分與背景圖做"AND"運(yùn)算:
進(jìn)過這一運(yùn)算所產(chǎn)生的結(jié)果如下圖
2.前景圖與背景圖做"OR"運(yùn)算
<1>前景圖中的彩色部分與圖第一步得到的“黑色易拉罐”圖做"OR"運(yùn)算:
<2>前景圖中的黑色部分與第一步得到的“黑色易拉罐”圖做"OR"運(yùn)算:
經(jīng)過這一運(yùn)算后所顯示的畫面就是所需的透明圖了,如下圖所示:
下面我們來看看實(shí)現(xiàn)上述透明貼圖效果的源代碼
[cpp] view plaincopy
#include "stdafx.h"
//全局變量聲明
HINSTANCE hInst;
HBITMAP bg,sprite; //聲明兩個(gè)位圖對(duì)象,分別存儲(chǔ)背景圖與前景易拉罐
HDC mdc; //聲明一個(gè)內(nèi)存DC"mdc",用來暫存位圖
//全局函數(shù)聲明
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void MyPaint(HDC hdc);
////****Winmain函數(shù),程序入口點(diǎn)函數(shù)**************************************
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
MyRegisterClass(hInstance);
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
//消息循環(huán)
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
//****設(shè)計(jì)一個(gè)窗口類,類似填空題,使用窗口結(jié)構(gòu)體*************************
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "canvas";
wcex.hIconSm = NULL;
return RegisterClassEx(&wcex);
}
//****初始化函數(shù)*************************************
// 1.建立與窗口DC兼容的內(nèi)存DC
// 2.從文件加載背景圖與恐龍圖
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
HDC hdc;
hInst = hInstance;
hWnd = CreateWindow("canvas", "繪圖窗口" , WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
MoveWindow(hWnd,10,10,600,450,true);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
hdc = GetDC(hWnd); //獲得窗口DC
mdc = CreateCompatibleDC(hdc); //創(chuàng)建與窗口兼容的內(nèi)存DC(mdc)
bg = (HBITMAP)LoadImage(NULL,"bg.bmp",IMAGE_BITMAP,600,450,LR_LOADFROMFILE);
//J加載背景圖到bg中
sprite = (HBITMAP)LoadImage(NULL,"sprite.bmp",IMAGE_BITMAP,170,99,LR_LOADFROMFILE);
//加載易拉罐圖到sprite中
MyPaint(hdc);
ReleaseDC(hWnd,hdc);
return TRUE;
}
//****自定義繪圖函數(shù)*********************************
//透明貼圖
void MyPaint(HDC hdc)
{
SelectObject(mdc,bg);
BitBlt(hdc,0,0,600,450,mdc,0,0,SRCCOPY); //先將背景圖貼到顯示窗口中
SelectObject(mdc,sprite); //選用易拉罐圖到"mdc"中
BitBlt(hdc,50,50,225,225,mdc,225,0,SRCAND);//進(jìn)行制作貼圖的第一步驟,即將屏蔽圖與背景圖做"AND"運(yùn)算,屏蔽圖在整張易拉罐圖中,最左上角起始位置點(diǎn)得坐標(biāo)為(225,0),BitBlt()函數(shù)中最后一個(gè)Raster參數(shù)值設(shè)置為SRCAND。
BitBlt(hdc,50,50,225,225,mdc,0,0,SRCPAINT);//進(jìn)行制作透明貼圖的第二步驟,即將前景圖與背景圖做"OR"運(yùn)算,前景圖在整張易拉罐圖中,最左上角起始位置的坐標(biāo)為(0,0),BitBlt()函數(shù)最后一個(gè)參數(shù)值設(shè)置為SRCPAINT。
}
//****消息處理函數(shù)**********************************
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_PAINT: //窗口重繪消息
hdc = BeginPaint(hWnd, &ps);
MyPaint(hdc);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY: //窗口結(jié)束消息
DeleteDC(mdc);
DeleteObject(bg);
DeleteObject(sprite);
PostQuitMessage(0);
break;
default: //其他消息
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
最后程序的運(yùn)行結(jié)果為:
通過BitBlt()貼圖函數(shù)及Raster運(yùn)算值的設(shè)定,很簡單地就做出了想要的透明效果,這種方法在設(shè)計(jì)2D游戲的一些畫面內(nèi)容時(shí)使用相當(dāng)頻繁。
本文名稱:VC++圖片透明技術(shù)原理
當(dāng)前地址:http://aaarwkj.com/article28/jeiicp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站制作、全網(wǎng)營銷推廣、品牌網(wǎng)站建設(shè)、定制開發(fā)、動(dòng)態(tài)網(wǎng)站、ChatGPT
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)