这是前两天遇到的一个问题,一幅图片含有要透明(或要屏蔽),即不显示的颜色(TransParentBlt),而且还需要使其半透明(AlphaBlend),例如显示效果为一个圆形的半透明球。上网搜了一下也没找到什么有用的信息,因此自己没办法自己想了一下,解决方法如下:
void AlphaBmp(HDC hdc,HBITMAP hBitmap,int x,int y,short limit,HRGN hRgn,COLORREF col)
{
BLENDFUNCTION blendfunc;
HDC hMaskDc;
HBITMAP hOld=NULL;
BITMAP Bmp;
blendfunc.BlendFlags=0;
blendfunc.AlphaFormat=0;
blendfunc.SourceConstantAlpha=(unsigned char)limit;
blendfunc.BlendOp=AC_SRC_OVER;
GetObject(hBitmap,sizeof(BITMAP),(LPSTR)&Bmp);
hMaskDc=CreateCompatibleDC(hdc);
hOld=(HBITMAP)SelectObject(hMaskDc,hBitmap);
HDC hTempDC=CreateCompatibleDC(hdc);
HBITMAP hBitmap2=CreateCompatibleBitmap(hdc,Bmp.bmWidth,Bmp.bmHeight);
hOld=(HBITMAP)SelectObject(hTempDC,hBitmap2);
BitBlt(hTempDC,0,0,Bmp.bmWidth,Bmp.bmHeight,hdc,x,y,SRCCOPY)
AlphaBlend (hTempDC,0,0,Bmp.bmWidth,Bmp.bmHeight,hMaskDc,0,0,Bmp.bmWidth,Bmp.bmHeight,blendfunc);
HRGN hR=CreateRectRgn(0,0,Bmp.bmWidth,Bmp.bmHeight);
HBRUSH hbr=CreateSolidBrush(col);
CombineRgn(hR,hR,hRgn,RGN_DIFF);
FillRgn(hTempDC,hR,hbr);
TransparentBlt(hdc,x,y,Bmp.bmWidth,Bmp.bmHeight,hTempDC,0,0,Bmp.bmWidth,Bmp.bmHeight,col);
SelectObject(hTempDC,hOld);
DeleteObject(hBitmap2);
DeleteObject(hR);
DeleteObject(hbr);
DeleteDC(hTempDC);
SelectObject(hMaskDc,hOld);
DeleteDC(hMaskDc);
}
参数的含义一次是:hdc为要显示图片的DC
hBitmap为要显示的图片句柄
x,y为坐标
limit为透明度(0-255)
hRgn为图片除掉要屏蔽的颜色的区域(对于球体就是一个圆形区域)
col为要屏蔽的颜色(例如一幅周围是白色的球,不显示周围的白色,只要球(白色就是屏蔽色))
对于hRgn有一点,怎么得到这个区域呢,看下面这个函数:
HRGN BitmapToRgn(HBITMAP hBitmap,COLORREF col)
{
HDC hMemDc;
HBITMAP hOld;
COLORREF CPixel;
HRGN rTemp,hGoal;
BITMAP Bmp;
GetObject(hBitmap,sizeof(BITMAP),&Bmp);
hMemDc=CreateCompatibleDC(NULL);
hOld=(HBITMAP)SelectObject(hMemDc,hBitmap);
hGoal=CreateRectRgn(0,0,Bmp.bmWidth,Bmp.bmHeight);
for(int x=0;x<=Bmp.bmWidth;x++)
for(int y=0;y<=Bmp.bmHeight;y++)
{
CPixel=GetPixel(hMemDc,x,y);
if(CPixel==col)
{
rTemp=CreateRectRgn(x,y,x+1,y+1);
CombineRgn(hGoal,hGoal,rTemp,RGN_XOR);
DeleteObject(rTemp);
}
}
SelectObject(hMemDc,hOld);
DeleteDC(hMemDc);
return hGoal;
}
参数一次是hBitmap为要得到区域的位图,col为屏蔽色
用法例子为:
HBITMAP hBitmap=LoadBitmap(GetModuleHandle(0),MAKEINTRESOURCE(IDB_BITMAP2));
HRGN hrgn=BitmapToRgn(hBitmap,RGB(255,0,255));
AlphaBmp(hDc,hBitmap,450,0,200,hrgn,RGB(255,0,255));
DeleteObject(hBitmap);
DeleteObject(hrgn);//为了提高速度,这个应该用全局变量保存,不易频繁删除