AlphaBlend是Window自带的GDI函数,在作GUI的时候为了达到更漂亮的效果我们常常用它.BLENDFUNCTION是AlphaBlend用控制透明效果的重要参数.定义如下:typedef struct _BLENDFUNCTION {
BYTE BlendOp;
BYTE BlendFlags;
BYTE SourceConstantAlpha;
BYTE AlphaFormat;
}BLENDFUNCTION, *PBLENDFUNCTION, *LPBLENDFUNCTION;BlendOp: 这个参数必须也只能为AC_SRC_OVER(0x00),意思就是把源图片覆盖到目标之上.BlendFlags: 必须为0SourceConstantAlpha: 简写为SCA,指定源图片的透明度,这个值是会和源图片的Alpha通道值合并计算的.AlphaFormat: 可以填两种,一种是0x00,一种是AC_SRC_ALPHA(0x01).填0的话,AlphaBlend据说就和BitBlt一样了,我没有试验过~填1的话,源DC必须是32位的DC不然的话,AlphaBlend会返回参数错误.计算公式(当SCA不是0xFF时): 输出像素(R,G,B,A) = 源像素(R,G,B,A) * SCA / 0xFF + 目标像素(R,G,B,A) * (1.0 - SCA / 0xFF)当SCA是0xFF时,计算公式 输出像素(R,G,B,A) = 源像素(R,G,B,A) + 目标像素(R,G,B,A) * (1.0 - 源像素(A) / 0xFF)混合计算公式 输出像素(R,G,B) = 源像素(R,G,B) * SCA / 0xFF + 目标像素(R,G,B) * (1.0 - 源像素(A) / 0xFF * SCA / 0xFF)
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/Vonger/archive/2009/08/24/4476654.aspx
有没有简单实例来看看,或解释一下这东西
BYTE BlendOp;
BYTE BlendFlags;
BYTE SourceConstantAlpha;
BYTE AlphaFormat;
}BLENDFUNCTION, *PBLENDFUNCTION, *LPBLENDFUNCTION;BlendOp: 这个参数必须也只能为AC_SRC_OVER(0x00),意思就是把源图片覆盖到目标之上.BlendFlags: 必须为0SourceConstantAlpha: 简写为SCA,指定源图片的透明度,这个值是会和源图片的Alpha通道值合并计算的.AlphaFormat: 可以填两种,一种是0x00,一种是AC_SRC_ALPHA(0x01).填0的话,AlphaBlend据说就和BitBlt一样了,我没有试验过~填1的话,源DC必须是32位的DC不然的话,AlphaBlend会返回参数错误.计算公式(当SCA不是0xFF时): 输出像素(R,G,B,A) = 源像素(R,G,B,A) * SCA / 0xFF + 目标像素(R,G,B,A) * (1.0 - SCA / 0xFF)当SCA是0xFF时,计算公式 输出像素(R,G,B,A) = 源像素(R,G,B,A) + 目标像素(R,G,B,A) * (1.0 - 源像素(A) / 0xFF)混合计算公式 输出像素(R,G,B) = 源像素(R,G,B) * SCA / 0xFF + 目标像素(R,G,B) * (1.0 - 源像素(A) / 0xFF * SCA / 0xFF)
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/Vonger/archive/2009/08/24/4476654.aspx
有没有简单实例来看看,或解释一下这东西
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);
http://topic.csdn.net/u/20100816/21/57dbace6-3e4e-4b7f-8b0a-a7f42b9befff.html
BYTE BlendOp;
BYTE BlendFlags;
BYTE SourceConstantAlpha;
BYTE AlphaFormat;
}BLENDFUNCTION, *PBLENDFUNCTION, *LPBLENDFUNCTION;
我试过AlphaFormat为0和AC_SRC_ALPHA(0x01)时的效果区别:AlphaFormat等于0时:SCA为SourceConstantAlpha
Dst.Red = Src.Red * (SCA/255.0) + Dst.Red * (1.0 - (SCA/255.0))
Dst.Green = Src.Green * (SCA/255.0) + Dst.Green * (1.0 - (SCA/255.0))
Dst.Blue = Src.Blue * (SCA/255.0) + Dst.Blue * (1.0 - (SCA/255.0))
则透明效果很好;每种颜色分量不会超过255;AlphaFormat等于AC_SRC_ALPHA(0x01)时:SCA为SourceConstantAlpha
源图像若为32位的,则原图像的每个像素的alpha值也会计算在内:
则计算结果会偏白,因为
Dst.Red = 一个公式
Dst.Green = 一个公式
Dst.Blue = 一个公式
每种颜色分量经常会大于255
void CFolderList::DrawPicture(CDC* pDC, int nIdex)
{
int nWith, nHeight;
CBitmap bmpIcon;
CBitmap *pOldBitmap;
CRect rectItem;
LVITEM itemInfo;
IMAGEINFO infoImage;
BLENDFUNCTION bfPicture;
CDC* pMemDC = new CDC;
CImageList* pImgList = GetImageList(LVSIL_NORMAL);
DWORD_PTR dwState = m_arrayItemState.GetAt(nIdex); pImgList->GetImageInfo(0, &infoImage);
nWith = infoImage.rcImage.right-infoImage.rcImage.left;
nHeight = infoImage.rcImage.bottom-infoImage.rcImage.top; //创建位图内存
bmpIcon.CreateCompatibleBitmap(pDC, nWith, nHeight);
pMemDC->CreateCompatibleDC(pDC);
pOldBitmap = pMemDC->SelectObject(&bmpIcon); itemInfo.mask = LVIF_IMAGE;
itemInfo.iItem = nIdex;
itemInfo.iSubItem = 0;
GetItem(&itemInfo);
pImgList->Draw(pMemDC, itemInfo.iImage, CPoint(0, 0), ILD_NORMAL); bfPicture.BlendOp = AC_SRC_OVER;
bfPicture.BlendFlags = 0;
bfPicture.AlphaFormat = 0;
bfPicture.SourceConstantAlpha = 255;
if(dwState & PICITEMSTATE_MOUSEOVER)
bfPicture.SourceConstantAlpha = 100; GetItemRect(nIdex, rectItem, LVIR_BOUNDS);
rectItem.bottom = rectItem.top+m_sizeItem.cy;
pDC->AlphaBlend(rectItem.left+m_nOffsetNormalX, rectItem.top+m_nOffsetNormalY, m_sizeIconNormal.cx, m_sizeIconNormal.cy, pMemDC, 0, 0, nWith, nHeight, bfPicture); if(dwState & PICITEMSTATE_MOUSEOVER)
{
Graphics graph(pDC->GetSafeHdc());
int nShowLeft = rectItem.left+m_nOffsetNormalX+m_sizeIconNormal.cx-m_pImageHook->GetWidth(),
nShowTop = rectItem.top+m_nOffsetNormalY+m_sizeIconNormal.cy-m_pImageX->GetHeight(); Point points[] = {
Point(nShowLeft, nShowTop),
Point(nShowLeft+m_pImageX->GetWidth(), nShowTop),
Point(nShowLeft, nShowTop+m_pImageX->GetHeight())
};
graph.DrawImage(m_pImageX, points, 3);
}
//释放内存
pMemDC->SelectObject(pOldBitmap);
ReleaseDC(pMemDC);
delete pMemDC;
}
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;
::AlphaBlend(pDC->m_hDC,r.left,r.top,r.Width(),r.Heigh(),memdc.m_hDC,0,0,r.Width(),r.Height(),bf);
memdc.SelectObject(pOldBitmap);
} 里面有些错误,我修改过了,但发现并没有效果?
你可以自己建个工程试试
AlphaBlend(pMemDC->m_hDC,10, 10, 160, 300, pBmpDC->m_hDC, 0, 0, 160, 300, bfInfo);然后#pragma comment(lib,"Msimg32.lib")最后可以运行了,但跟前面的一样没效果?难道是我的位图的原因?你可否截你的效果图给我看看效果
基本达到我的目的了,很感谢。
位图那里我无法修改,超过256色,不给打开
但效果我看到了,我主要想知道实现的是什么效果
之前我想实现类似的效果,用的是SetLayeredWindowAttributes
但结果整个窗口的透明度都给修改了,我只好靠多层窗口来实现然后今天偶然看到这个函数,听说也是实现半透明效果,所以我想探究一下。