1. 程式人生 > >設定透明背景圖片

設定透明背景圖片

背景:

            有兩個圖片,一個是目標背景圖片, 一個是帶有自身背景色彩的彩色圖片

            先將這彩色圖片繪製到目標背景圖片中, 這一步通過BITBLT就可實現。   但實現後的效果是: 目標圖片上,繪製上去的彩色圖片帶有其本身的背景。

       問題就來了, 我們想將彩色圖片本身的背景去掉,應該如何解決?

解決方法:

          使用API函式:TransparentBlt   此函式將原DC中的圖片繪製到目標DC中,並同時設定原圖形在目標圖形上的透明色。

BOOL TransparentBlt(
  HDC hdcDest,        // handle to destination DC
  int nXOriginDest,   // x-coord of destination upper-left corner
  int nYOriginDest,   // y-coord of destination upper-left corner
  int nWidthDest,     // width of destination rectangle
  int hHeightDest,    // height of destination rectangle
  HDC hdcSrc,         // handle to source DC
  int nXOriginSrc,    // x-coord of source upper-left corner
  int nYOriginSrc,    // y-coord of source upper-left corner
  int nWidthSrc,      // width of source rectangle
  int nHeightSrc,     // height of source rectangle
  UINT crTransparent  // color to make transparent
);


   如本例中,將透明色設定為彩色圖形自帶背景色時, 則使用此函式後,所得最終圖形上彩色圖形的自身背景色就消除了。

   示例:

		CDC* pDC=GetDC();

		CBitmap bmp;
		bmp.LoadBitmap(IDB_BITMAP1);

		BITMAP bmpInfo;
		bmp.GetObject(sizeof(BITMAP),&bmpInfo);


		CDC ImageDC;
		ImageDC.CreateCompatibleDC(pDC);
		
		CBitmap *pOldImageBmp=ImageDC.SelectObject(&bmp);


		CBitmap bmpBK;
		bmpBK.LoadBitmap(IDB_BITMAP2);

		BITMAP bmpBkInfo;
	    bmpBK.GetObject(sizeof(BITMAP),&bmpBkInfo);

		CDC bkDC;
		bkDC.CreateCompatibleDC(pDC);

		bkDC.SelectObject(&bmpBK);

		TransparentBlt(bkDC.m_hDC,100,150,bmpInfo.bmWidth,bmpInfo.bmHeight,ImageDC.m_hDC,0,0,bmpInfo.bmWidth,bmpInfo.bmHeight,RGB(255,0,0)); // 設定紅色為透明色

		BitBlt(pDC->m_hDC,0,0,bmpBkInfo.bmWidth,bmpBkInfo.bmHeight,bkDC.m_hDC,0,0,SRCCOPY); //畫到螢幕上

原理: 通過設定掩碼點陣圖來實現

              1)首先建立掩碼點陣圖

              2)使用掩碼點陣圖作用於彩色原圖,得到變異新圖(透明色為黑,其他區域為原色)

              3)使用掩碼點陣圖與目標背景圖相與 (透明區域為透明色,其他區域為黑色)

              4)使用變異新圖與目標背景圖相或  ,得到最終圖

圖例如下:

       希望將上面小圖的自身背景色去掉,得到最終圖

所採取的步驟如下:

程式碼:

void TransparentBlt2( HDC hdcDest,      // 目標DC
					 int nXOriginDest,   // 目標X偏移
					 int nYOriginDest,   // 目標Y偏移
					 int nWidthDest,     // 目標寬度
					 int nHeightDest,    // 目標高度
					 HDC hdcSrc,         // 源DC
					 int nXOriginSrc,    // 源X起點
					 int nYOriginSrc,    // 源Y起點
					 int nWidthSrc,      // 源寬度
					 int nHeightSrc,     // 源高度
					 UINT crTransparent  // 透明色,COLORREF型別
					 )
{
	HBITMAP hOldImageBMP, hImageBMP = CreateCompatibleBitmap(hdcDest, nWidthDest, nHeightDest);	// 建立相容點陣圖
	HBITMAP hOldMaskBMP, hMaskBMP = CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL);			// 建立單色掩碼點陣圖
	HDC		hImageDC = CreateCompatibleDC(hdcDest);
	HDC		hMaskDC = CreateCompatibleDC(hdcDest);
	hOldImageBMP = (HBITMAP)SelectObject(hImageDC, hImageBMP);
	hOldMaskBMP = (HBITMAP)SelectObject(hMaskDC, hMaskBMP);

	// 將源DC中的點陣圖拷貝到臨時DC中
	if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc)
		BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY);
	else
		StretchBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, 
		hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);

	// 設定透明色
	SetBkColor(hImageDC, crTransparent);

	// 生成透明區域為白色,其它區域為黑色的掩碼點陣圖
	BitBlt(hMaskDC, 0, 0, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCCOPY);

	// 生成透明區域為黑色,其它區域保持不變的點陣圖
	SetBkColor(hImageDC, RGB(0,0,0));
	SetTextColor(hImageDC, RGB(255,255,255));
	BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);

	// 透明部分保持螢幕不變,其它部分變成黑色
	SetBkColor(hdcDest,RGB(255,255,255));
	SetTextColor(hdcDest,RGB(0,0,0));


	BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);

	// "或"運算,生成最終效果
	BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCPAINT);

	// 清理、恢復	
	SelectObject(hImageDC, hOldImageBMP);
	DeleteDC(hImageDC);
	SelectObject(hMaskDC, hOldMaskBMP);
	DeleteDC(hMaskDC);
	DeleteObject(hImageBMP);
	DeleteObject(hMaskBMP);
}


參考資料: