前面有篇文章講到如何進行透明貼圖,其實主要用在一些不規則控制項UI的製作上面。那個用到的方法是製作一張掩碼位元影像,然後利用BitBlt提供的一些光柵操作進行透明繪製。
有時候人家可能僅僅提供一張需要透明顯示的位元影像,而並沒有同步提供掩碼位元影像,怎麼辦呢?非要人家提供或者我們自己製作一張? 太麻煩了,有沒有簡單的程式實現方法?本文將簡單介紹下通過程式如果建立給定位元影像的掩碼位元影像,然後繪製透明效果。
其實在使用ImageLIst的時候我們就應該知道,如果ImageList的是Icon,由於本身Icon就可以是透明的,所以不需要指定什麼透明色;但是如果ImageList的item是Bitmap,而我們想要透明繪製的話,就需要制定透明色,也就是位元影像掩碼色。同樣的道理,對於給定的位元影像同時,需要為其指定掩碼色maskColor。
下面簡單介紹下繪製的整個流程。
假設需要在制定視窗下繪製資源id為IDB_BITMAP1的位元影像。方法如下:
1、建立相容DC,載入指定的位元影像資源,將其選入到前面建立的相容dc中
HBITMAP hbmp = ::LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP1));
BITMAP bmpInfo;
::GetObject((HGDIOBJ)hbmp, sizeof(BITMAP), &bmpInfo);
HWND hDesktop = ::GetDesktopWindow();
HDC hDesktopDC = ::GetDC(hDesktop);
HDC hSrcDc = ::CreateCompatibleDC(hDesktopDC);
HBITMAP hSrcBitmap = ::CreateCompatibleBitmap(hDesktopDC, bmpInfo.bmWidth, bmpInfo.bmHeight);
::SelectObject(hSrcDc, hbmp);
2、建立單色掩碼位元影像(和原圖一般大小,其中原圖掩碼色部分為白色,其它為黑色)
::SetBkColor(hSrcDc, RGB(0xff, 0, 0xff)); // 將透明色設定為背景色
HDC hMaskDC = ::CreateCompatibleDC(hDesktopDC);
HBITMAP hMaskBmp = ::CreateBitmap(bmpInfo.bmWidth, bmpInfo.bmHeight, 1, 1, 0);
HBITMAP hOldMaskBmp = (HBITMAP)::SelectObject(hMaskDC, hMaskBmp);
::BitBlt(hMaskDC, 0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, hSrcDc, 0, 0, SRCCOPY);
3、修改源圖,使得其顏色圖部分為黑色
:SetBkColor(hSrcDc, RGB(0, 0, 0));
::SetTextColor(hSrcDc, RGB(0xff, 0xff, 0xff));
::BitBlt(hSrcDc, 0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, hMaskDC, 0, 0, SRCAND);
4、擷取要繪製的視窗dc,並且進行透明繪製
HDC hdcMainWnd = ::GetDC(g_hMainWnd); // 要繪製的視窗dc
::SetBkColor(hdcMainWnd, RGB(0xff, 0xff, 0xff));
::SetTextColor(hdcMainWnd, RGB(0, 0, 0));
::BitBlt(hdcMainWnd, 0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, hMaskDC, 0, 0, SRCAND);
::BitBlt(hdcMainWnd, 0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, hSrcDc, 0, 0, SRCPAINT);
也就上述4個步驟。這裡主要用到BitBlt的幾個光柵操作。需要注意的是在BitBlt操作中,如果srcDC和dstDC的位元影像格式不一樣的話,需要進行相應的格式轉換。也就是單色位元影像到彩色位元影像的轉換規則,這個看看msdn關於BitBlt的說明即可,充分利用到dstDC的前景色彩和背景色。這也是為啥上述代碼中頻繁調用SetBkColor和SetTextColor的目的所在。由於只是解釋繪製原理用,幾乎所有的資源都沒有刪除(ReleaseDC)和恢複(SelectObject等)。
轉自http://blog.csdn.net/doudouhuy/article/details/4218548