前一阵子我的博客中有篇图片透明处理的文章,下面对它做个补充。这里也可以用在EVC和VC的各个版本上
1、透明:包括关键色透明和alpha透明,关键色透明就是选择一种颜色作为透明色,一般选取背景色。
alpha透明就是和背景融合,一般范围是0~255,数值越小背景越明显,0表示完全透明,255表示不透明
公式
dstred = srcred * (alpha / 255.0) + dstred * (1.0 - alpha / 255.0);
dstred = srcred * (alpha / 255.0) + dstred * (1.0 - alpha / 255.0);
dstred = srcred * (alpha / 255.0) + dstred * (1.0 - alpha / 255.0);
2、窗口透明
2.1、如果系统是2000以上可以设置窗口的透明属性如下:
//至少需要Windows 2000系统
ModifyStyleEx(0,WS_EX_LAYERED); //修改Window的风格
//如果不设置属性,窗口就看不到
//SetLayeredWindowAttributes(GetSysColor(COLOR_BTNFACE),0,LWA_COLORKEY); //透明色是按钮背景颜色 这个就可以实现不规则窗口
SetLayeredWindowAttributes(0,0,LWA_ALPHA); //半透明
//SetLayeredWindowAttributes(GetSysColor(COLOR_BTNFACE),128,LWA_COLORKEY | LWA_ALPHA); //两个混合
注意要设置_WIN32_WINNT的值 0x500
把上面的代码加入窗体初始化代码中就可以了。
.2、
如果是2000以下的系统,可以设置窗口的Region来达到关键色透明效果
void MyWnd::SetRegion(COLORREF clrTrans)
{
m_bmp.LoadBitmap(IDB_BITMAP1); //读取位图资源
BITMAP bm;
CSize sz;
m_bmp.GetBitmap(&bm);
sz.cx = bm.bmWidth;
sz.cy = bm.bmHeight;
unsigned char *pBuffer = new unsigned char[sz.cx * sz.cy * (bm.bmBitsPixel >> 3)];
m_bmp.GetBitmapBits(sz.cx * sz.cy * (bm.bmBitsPixel >> 3),pBuffer);
unsigned char *pOriBuffer = pBuffer;
CRgn rgn,rgn2;
rgn.CreateRectRgn(0,0,sz.cx,sz.cy);
rgn2.CreateRectRgn(0,0,1,1);
int off = (bm.bmBitsPixel >> 3);
for(int y = 0; y < sz.cy; y++)
{
for(int x = 0; x < sz.cx; x++)
{
if(((*pBuffer) == 255) && ((*(pBuffer + 1)) == 0) && ((*(pBuffer + 2)) == 255))
{
rgn2.SetRectRgn(x,y,x + 1,y + 1);
rgn.CombineRgn(&rgn,&rgn2,RGN_DIFF);
}
pBuffer += off;
}
}
delete []pOriBuffer;
SetWindowRgn((HRGN)rgn.GetSafeHandle(),TRUE);
}
3、AlphaBlend Alpha透明
//绘制可以透明的矩形
void DrawAlphaRect(CDC *pDC,CRect& r,COLORREF clr,unsigned char alpha)
{
CDC memdc;
memdc.CreateCompatibleDC(pDC);
CBitmap bmp,*pOldBitmap;
bmp.CreateCompatibleBitmap(pDC,r.Width(),r.Height());
pOldBitmap = memdc.SelectObject(&bmp);
memdc.FillSolidRect(0,0,r.Width(),r.Height(),clr);
BLENDFUNCTION bf;
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = alpha;
bf.AlphaFormat = 0;
pDC->AlphaBlend(r.left,r.top,r.Width(),r.Height(),&memdc,0,0,r.Width(),r.Height(),bf);
memdc.SelectObject(pOldBitmap);
}
//绘制可以透明的位图
void DrawAlphaBitmap(CDC *pDC,CRect& r,CBitmap& bmp,unsigned char alpha)
{
CDC memdc;
memdc.CreateCompatibleDC(pDC);
CBitmap *pOldBitmap;
CSize sz = bmp.GetBitmapDimension();
BITMAP bm;
bmp.GetBitmap(&bm);
sz.SetSize(bm.bmWidth,bm.bmHeight);
pOldBitmap = memdc.SelectObject(&bmp);
BLENDFUNCTION bf;
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = alpha;
bf.AlphaFormat = 0;
pDC->AlphaBlend(r.left,r.top,r.Width(),r.Height(),&memdc,0,0,sz.cx,sz.cy,bf);
memdc.SelectObject(pOldBitmap);
}
这样调用
COLORREF clr = RGB(141,173,223);
DrawAlphaRect(pDC,CRect(10,50,500,400),clr,192);
DrawAlphaBitmap(pDC,CRect(10,10,300,200),bmp,128);
1、透明:包括关键色透明和alpha透明,关键色透明就是选择一种颜色作为透明色,一般选取背景色。
alpha透明就是和背景融合,一般范围是0~255,数值越小背景越明显,0表示完全透明,255表示不透明
公式
dstred = srcred * (alpha / 255.0) + dstred * (1.0 - alpha / 255.0);
dstred = srcred * (alpha / 255.0) + dstred * (1.0 - alpha / 255.0);
dstred = srcred * (alpha / 255.0) + dstred * (1.0 - alpha / 255.0);
2、窗口透明
2.1、如果系统是2000以上可以设置窗口的透明属性如下:
//至少需要Windows 2000系统
ModifyStyleEx(0,WS_EX_LAYERED); //修改Window的风格
//如果不设置属性,窗口就看不到
//SetLayeredWindowAttributes(GetSysColor(COLOR_BTNFACE),0,LWA_COLORKEY); //透明色是按钮背景颜色 这个就可以实现不规则窗口
SetLayeredWindowAttributes(0,0,LWA_ALPHA); //半透明
//SetLayeredWindowAttributes(GetSysColor(COLOR_BTNFACE),128,LWA_COLORKEY | LWA_ALPHA); //两个混合
注意要设置_WIN32_WINNT的值 0x500
把上面的代码加入窗体初始化代码中就可以了。
.2、
如果是2000以下的系统,可以设置窗口的Region来达到关键色透明效果
void MyWnd::SetRegion(COLORREF clrTrans)
{
m_bmp.LoadBitmap(IDB_BITMAP1); //读取位图资源
BITMAP bm;
CSize sz;
m_bmp.GetBitmap(&bm);
sz.cx = bm.bmWidth;
sz.cy = bm.bmHeight;
unsigned char *pBuffer = new unsigned char[sz.cx * sz.cy * (bm.bmBitsPixel >> 3)];
m_bmp.GetBitmapBits(sz.cx * sz.cy * (bm.bmBitsPixel >> 3),pBuffer);
unsigned char *pOriBuffer = pBuffer;
CRgn rgn,rgn2;
rgn.CreateRectRgn(0,0,sz.cx,sz.cy);
rgn2.CreateRectRgn(0,0,1,1);
int off = (bm.bmBitsPixel >> 3);
for(int y = 0; y < sz.cy; y++)
{
for(int x = 0; x < sz.cx; x++)
{
if(((*pBuffer) == 255) && ((*(pBuffer + 1)) == 0) && ((*(pBuffer + 2)) == 255))
{
rgn2.SetRectRgn(x,y,x + 1,y + 1);
rgn.CombineRgn(&rgn,&rgn2,RGN_DIFF);
}
pBuffer += off;
}
}
delete []pOriBuffer;
SetWindowRgn((HRGN)rgn.GetSafeHandle(),TRUE);
}
3、AlphaBlend Alpha透明
//绘制可以透明的矩形
void DrawAlphaRect(CDC *pDC,CRect& r,COLORREF clr,unsigned char alpha)
{
CDC memdc;
memdc.CreateCompatibleDC(pDC);
CBitmap bmp,*pOldBitmap;
bmp.CreateCompatibleBitmap(pDC,r.Width(),r.Height());
pOldBitmap = memdc.SelectObject(&bmp);
memdc.FillSolidRect(0,0,r.Width(),r.Height(),clr);
BLENDFUNCTION bf;
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = alpha;
bf.AlphaFormat = 0;
pDC->AlphaBlend(r.left,r.top,r.Width(),r.Height(),&memdc,0,0,r.Width(),r.Height(),bf);
memdc.SelectObject(pOldBitmap);
}
//绘制可以透明的位图
void DrawAlphaBitmap(CDC *pDC,CRect& r,CBitmap& bmp,unsigned char alpha)
{
CDC memdc;
memdc.CreateCompatibleDC(pDC);
CBitmap *pOldBitmap;
CSize sz = bmp.GetBitmapDimension();
BITMAP bm;
bmp.GetBitmap(&bm);
sz.SetSize(bm.bmWidth,bm.bmHeight);
pOldBitmap = memdc.SelectObject(&bmp);
BLENDFUNCTION bf;
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = alpha;
bf.AlphaFormat = 0;
pDC->AlphaBlend(r.left,r.top,r.Width(),r.Height(),&memdc,0,0,sz.cx,sz.cy,bf);
memdc.SelectObject(pOldBitmap);
}
这样调用
COLORREF clr = RGB(141,173,223);
DrawAlphaRect(pDC,CRect(10,50,500,400),clr,192);
DrawAlphaBitmap(pDC,CRect(10,10,300,200),bmp,128);