windows程式設計筆記【十】透明背景效果
阿新 • • 發佈:2019-02-06
圖片都是以四方格儲存的,如果要把他貼到背景圖上,就會這樣:
可是對於LoadImage()是不支援png這類帶有透明通道的圖片的,如果不用其他的庫,如GDI+,怎麼實現背景透明呢?
原理如下:
我們使用一個貼圖來去掉黑色背景
左邊是 要去背並且貼到背景上的前景圖,右邊黑邊稱之為遮蔽圖,在透明過程會用到他。
- 將遮蔽圖於背景圖做 “AND” 運算,貼到目標DC中
- 將上一步處理後的圖片和前景圖做 “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運算
效果如下: