正确显示透明位图
网上已经有了不少地关于如果透明显示位图的文档,但是这些文章中有一个非常大的缺陷,如果当一个位图并不是24位色彩的位图时,换句话说,当一个位图是2位或4位或8位的位图时,由于这些位图使用调色板信息,使用一般的透明显示位图的方法,将会出现色彩错乱的现象,不能正确地显示一个透明的位图。
我在前人文档的基础上,对他们的显示方法做了一些修正,则可以正确地显示任何位数色彩的透明位图。下面的DrawTransparentBmp函数是一个完整的正确显示透明位图的函数,其各参数说明如下:HDC hdc:目标HDC,即将要绘制位图的HDCHBITMAP hbmp:位图的句柄,此位图可以是2位、4位、8位、16位、24位位图。RECT &rect:将要绘制的区域COLORREF colorTrans:透明色
函数清单如下:BOOL DrawTransparentBmp(HDC hdc, HBITMAP hbmp, RECT &rect, COLORREF colorTrans){ HDC dcImage, dcTrans, dcImage24; HBITMAP holdbmp24, hbmp24; HBITMAP holdbmp; HBITMAP hbmpTrans, holdbmpTrans;
// 创建内存DC dcImage = CreateCompatibleDC(hdc); dcTrans = CreateCompatibleDC(hdc); dcImage24 = CreateCompatibleDC(hdc);
if (dcImage == NULL || dcTrans == NULL || dcImage24 == NULL) // Error: can't create compatible dc return FALSE; // 获得图像属性 BITMAP bmp; GetObject(hbmp, sizeof(bmp), &bmp);
// 选择图片到dcImage中 holdbmp = (HBITMAP)SelectObject(dcImage, hbmp);
// 创建24色位图,这样才能正确地显示带透明色的位图 LPBITMAPINFO lpBmpInfo; lpBmpInfo = (BITMAPINFO*) new BYTE[sizeof(BITMAPINFOHEADER)]; lpBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); lpBmpInfo->bmiHeader.biPlanes = 1; lpBmpInfo->bmiHeader.biBitCount = nBitCount; lpBmpInfo->bmiHeader.biCompression = BI_RGB; lpBmpInfo->bmiHeader.biSizeImage = 0; lpBmpInfo->bmiHeader.biClrUsed = 0; lpBmpInfo->bmiHeader.biWidth = bmp.bmWidth; lpBmpInfo->bmiHeader.biHeight = bmp.bmHeight; HDC dc = CreateCompatibleDC(NULL); // 创建新图片 LPVOID lpBits; hbmp24 =::CreateDIBSection(dc,lpBmpInfo,DIB_RGB_COLORS, &lpBits,NULL,0); DeleteDC(dc); delete lpBmpInfo;
if (hbmp24 == NULL) // Error return FALSE;
holdbmp24 = (HBITMAP)SelectObject(dcImage24, hbmp24);
// 将原图片绘制到24色位图中 BitBlt(dcImage24, 0, 0, bmp.bmWidth, bmp.bmHeight, dcImage, 0, 0, SRCCOPY);
// 创建Mask位图 hbmpTrans = CreateBitmap(bmp.bmWidth, bmp.bmHeight, 1, 1, NULL); if (hbmpTrans == NULL) // Error return FALSE;
// 选择mask位图到dcTrans中 holdbmpTrans = (HBITMAP)SelectObject(dcTrans, hbmpTrans); // 创建掩码图像(基于指定的颜色) COLORREF oldbkcolor = SetBkColor(dcImage24, colorTrans); BitBlt(dcTrans, 0, 0, bmp.bmWidth, bmp.bmHeight, dcImage24, 0, 0, SRCCOPY); SetBkColor(dcImage24, RGB(0,0,0)); COLORREF oldtextcolor = SetTextColor(dcImage24, RGB(255,255,255)); BitBlt(dcImage24, 0, 0, bmp.bmWidth, bmp.bmHeight, dcTrans, 0, 0, SRCAND);
// 去除指定的颜色 COLORREF crOldBack, crOldText; crOldBack = SetBkColor(hdc, RGB(255,255,255)); crOldText = SetTextColor(hdc, RGB(0,0,0));
// 显示透明位图 StretchBlt(hdc, rect.left, rect.top, rect.right - rect.left,rect.bottom - rect.top, dcTrans, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCAND); StretchBlt(hdc, rect.left, rect.top, rect.right - rect.left,rect.bottom - rect.top, dcImage24, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCPAINT); // 恢复设置及释放资源 SelectObject(dcImage, holdbmp); SelectObject(dcImage24, holdbmp24); SelectObject(dcTrans, holdbmpTrans);
DeleteObject(hbmp24); DeleteObject(hbmpTrans);
SetBkColor(hdc, crOldBack); SetTextColor(hdc, crOldText); SetBkColor(dcImage24, oldbkcolor); SetTextColor(dcImage24, oldtextcolor);
DeleteDC(dcImage); DeleteDC(dcImage24); DeleteDC(dcTrans);
return TRUE;}
阿文http://tulipstudio.yeah.net