1. 程式人生 > >windows程式設計筆記【十】透明背景效果

windows程式設計筆記【十】透明背景效果

圖片都是以四方格儲存的,如果要把他貼到背景圖上,就會這樣: 

 可是對於LoadImage()是不支援png這類帶有透明通道的圖片的,如果不用其他的庫,如GDI+,怎麼實現背景透明呢?

原理如下:

我們使用一個貼圖來去掉黑色背景

左邊是 要去背並且貼到背景上的前景圖,右邊黑邊稱之為遮蔽圖,在透明過程會用到他。

  1. 將遮蔽圖於背景圖做 “AND” 運算,貼到目標DC中
  2. 將上一步處理後的圖片和前景圖做 “OR”運算,貼到目的地DC中。

為什麼這兩步就能產生透明呢,來闡述一下究竟發生了什麼:

and運算是兩數都為1,即為1,其他都是0:1&1=1; 1&0=0; 0&1=0; 0&0=0;

遮蔽圖黑色部分與背景彩色部分and運算後都變成黑的。

遮蔽圖白色部分和背景圖彩色部分and後還是彩的。

第一步效果如下:

步驟2:or運算:0&0=0、0&1=1、1&0=1、1&1=1

效果如下:

程式碼如下:

void MyPaint(HDC hdc)
{	
	SelectObject(mdc, hbmp);  
	BitBlt(hdc, 0, 0, 600, 450, mdc, 0, 0, SRCCOPY); //顯示背景圖

	SelectObject(mdc, bg);
	BitBlt(hdc, 50, 50, 85, 99, mdc, 85, 0, SRCAND); //SRCAND為AND運算
	BitBlt(hdc, 50, 50, 85, 99, mdc, 0, 0, SRCPAINT); //SRCPAINT為OR運算
}

BOOL InitInstance(HINSTANCE hinstance)
{
	HWND hwnd;
	HDC hdc;
	if (!(hwnd = CreateWindowEx(NULL,
		"WINCLASS1",	//winclass.lpszClassName設定的字元,是類的別名。
		"YouWindows",	//視窗的名稱
		WS_OVERLAPPEDWINDOW | WS_VISIBLE,	//一些視窗屬性
		0, 0,			//視窗位置
		600, 450,		//視窗寬高
		NULL,			//父視窗控制代碼
		NULL,			//附屬視窗控制代碼
		hinstance,		//WinMain第一個實參,程式控制代碼。
		NULL			//null就可以了
	)))
		return false;
//上邊是視窗函式,無關

	hdc = GetDC(hwnd);
	mdc = CreateCompatibleDC(hdc);
	hbmp = (HBITMAP)LoadImage(NULL, "無標題.bmp", IMAGE_BITMAP, 600, 450, LR_LOADFROMFILE); //載入背景圖
	bg = (HBITMAP)LoadImage(NULL, "1333765851_1860.bmp", IMAGE_BITMAP, 170, 99, LR_LOADFROMFILE); //載入前景圖和遮蔽圖,他們是一張。
	MyPaint(hdc);
	ReleaseDC(hwnd, hdc);
	return true;
}

 注意!以上程式碼遮蔽圖和前景圖是一張,只是用了兩個不同的位置載入而已。

BitBlt(hdc, 50, 50, 85, 99, mdc, 85, 0, SRCAND); //遮蔽圖x軸85畫素做AND運算
BitBlt(hdc, 50, 50, 85, 99, mdc, 0, 0, SRCPAINT); //前景圖在x軸0畫素開始做OR運算

效果如下: