透明位图的显示.docx
《透明位图的显示.docx》由会员分享,可在线阅读,更多相关《透明位图的显示.docx(11页珍藏版)》请在冰点文库上搜索。
透明位图的显示
透明位图的显示
作者:
王骏
下载本文示例代码
包含透明色的位图的绘制方法有多种,最简单的方法是调用现成的函数:
TransparentBlt,也可以通过自己的代码实现类似TransparentBlt的功能,实现过程也有两种形式,一种是事先做一张掩码位图,另一种是动态生成掩码位图。
本文将介绍动态生成掩码位图绘制具有透明区域位图的方法。
一、TransparentBlt函数的使用
TransparentBlt函数在Windows98/Windows2000以上版本运行,系统中需要包含Msimg32.dll,使用时可以链接Msimg32.lib。
Windows98下的TransparentBlt会产生资源泄漏,所以不建议在WIN98下使用该函数。
TransparentBlt函数原型如下:
BOOLTransparentBlt(
HDChdcDest,//目标DC
intnXOriginDest,//目标X偏移
intnYOriginDest,//目标Y偏移
intnWidthDest,//目标宽度
inthHeightDest,//目标高度
HDChdcSrc,//源DC
intnXOriginSrc,//源X起点
intnYOriginSrc,//源Y起点
intnWidthSrc,//源宽度
intnHeightSrc,//源高度
UINTcrTransparent//透明色,COLORREF类型
);
使用示例:
CBitmapFootballBMP;
FootballBMP.LoadBitmap(IDB_FOOTBALLBMP);
CDCImageDC;
ImageDC.CreateCompatibleDC(pDC);
CBitmap*pOldImageBMP=ImageDC.SelectObject(&FootballBMP);
TransparentBlt(pDC->m_hDC,0,0,218,199,ImageDC.m_hDC,0,0,218,199,RGB(0,0,0xff));
ImageDC.SelectObject(pOldImageBMP);
二、实现TransparentBlt函数
为了理解具有透明色位图的绘制过程,我们来亲手建立一个具有同TransparentBlt功能一致的实验函数,称之为TransparentBlt2。
实验素材:
有两张位图:
bk.bmp是背景位图,football.bmp包含透明区域,透明色为蓝色RGB(0,0,0xff)
实验目的:
以bk.bmp为背景,将football.bmp绘制到背景中,形成如下的最终效果图。
2.1透明位图绘制原理
假设football.bmp->载入HBITMAPhImageBMP->选入HDChImageDC
2.1.1生成足球的单色掩码位图,透明区域为白色(全1),非透明区域为黑色(全0)
HBITMAPhMaskBMP=CreateBitmap(nWidthDest,nHeightDest,1,1,NULL);//建立单色位图
SetBkColor(hImageDC,RGB(0,0,0xff));//设置背景色为蓝色
BitBlt(hMaskDC,0,0,nWidthDest,nHeightDest,hImageDC,0,0,SRCCOPY);//拷贝到hMaskDC
这样足球位图中蓝色区域在掩码位图中成了白色,其它区域为黑色,此时hMaskBMP如下图:
(图一)
2.1.2设置背景色为黑色,前景色为白色,将掩码位图(图一)与足球位图相"与"
SetBkColor(hImageDC,RGB(0,0,0));
SetTextColor(hImageDC,RGB(255,255,255));
BitBlt(hImageDC,0,0,nWidthDest,nHeightDest,hMaskDC,0,0,SRCAND);
这样,掩码位图中背景色(黑色)的区域在hImageBMP中被保留,前景色(白色)的部分变为黑色。
此时hImageBMP如下图:
(图二)
2.1.3设置背景色为白色,前景色为黑色,将掩码位图(图一)与背景进行“与”运算
SetBkColor(hdcDest,RGB(255,255,255));
SetTextColor(hdcDest,RGB(0,0,0));
BitBlt(hdcDest,nXOriginDest,nYOriginDest,nWidthDest,nHeightDest,hMaskDC,0,0,SRCAND);
掩码中白色区域(数据与1相“与”结果不变)使背景保持不变,黑色区域变成黑色,此时背景显示如下:
(图三)
2.1.4将hImageBMP(图二)与背景(图三)进行“或”运算
BitBlt(hdcDest,nXOriginDest,nYOriginDest,nWidthDest,nHeightDest,hImageDC,0,0,SRCPAINT);
这样就将足球绘制到背景上了。
2.2TransparentBlt2函数全部实现代码
voidTransparentBlt2(HDChdcDest,//目标DC
intnXOriginDest,//目标X偏移
intnYOriginDest,//目标Y偏移
intnWidthDest,//目标宽度
intnHeightDest,//目标高度
HDChdcSrc,//源DC
intnXOriginSrc,//源X起点
intnYOriginSrc,//源Y起点
intnWidthSrc,//源宽度
intnHeightSrc,//源高度
UINTcrTransparent//透明色,COLORREF类型
)
{
HBITMAPhOldImageBMP,hImageBMP=CreateCompatibleBitmap(hdcDest,nWidthDest,nHeightDest);//创建兼容位图
HBITMAPhOldMaskBMP,hMaskBMP=CreateBitmap(nWidthDest,nHeightDest,1,1,NULL);//创建单色掩码位图
HDChImageDC=CreateCompatibleDC(hdcDest);
HDChMaskDC=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);
}
2.3TransparentBlt的另外一个版本:
TransparentBltU
TransparentBltU是ChristianGraus在WinDEV发表的一个函数,功能与TransparentBlt一致,以下是全部实现代码:
boolTransparentBltU(
HDCdcDest,//handletoDestDC
intnXOriginDest,//x-coordofdestinationupper-leftcorner
intnYOriginDest,//y-coordofdestinationupper-leftcorner
intnWidthDest,//widthofdestinationrectangle
intnHeightDest,//heightofdestinationrectangle
HDCdcSrc,//handletosourceDC
intnXOriginSrc,//x-coordofsourceupper-leftcorner
intnYOriginSrc,//y-coordofsourceupper-leftcorner
intnWidthSrc,//widthofsourcerectangle
intnHeightSrc,//heightofsourcerectangle
UINTcrTransparent//colortomaketransparent
)
{
if(nWidthDest<1)returnfalse;
if(nWidthSrc<1)returnfalse;
if(nHeightDest<1)returnfalse;
if(nHeightSrc<1)returnfalse;
HDCdc=CreateCompatibleDC(NULL);
HBITMAPbitmap=CreateBitmap(nWidthSrc,nHeightSrc,1,GetDeviceCaps(dc,
BITSPIXEL),NULL);
if(bitmap==NULL)
{
DeleteDC(dc);
returnfalse;
}
HBITMAPoldBitmap=(HBITMAP)SelectObject(dc,bitmap);
if(!
BitBlt(dc,0,0,nWidthSrc,nHeightSrc,dcSrc,nXOriginSrc,
nYOriginSrc,SRCCOPY))
{
SelectObject(dc,oldBitmap);
DeleteObject(bitmap);
DeleteDC(dc);
returnfalse;
}
HDCmaskDC=CreateCompatibleDC(NULL);
HBITMAPmaskBitmap=CreateBitmap(nWidthSrc,nHeightSrc,1,1,NULL);
if(maskBitmap==NULL)
{
SelectObject(dc,oldBitmap);
DeleteObject(bitmap);
DeleteDC(dc);
DeleteDC(maskDC);
returnfalse;
}
HBITMAPoldMask=(HBITMAP)SelectObject(maskDC,maskBitmap);
SetBkColor(maskDC,RGB(0,0,0));
SetTextColor(maskDC,RGB(255,255,255));
if(!
BitBlt(maskDC,0,0,nWidthSrc,nHeightSrc,NULL,0,0,BLACKNESS))
{
SelectObject(maskDC,oldMask);
DeleteObject(maskBitmap);
DeleteDC(maskDC);
SelectObject(dc,oldBitmap);
DeleteObject(bitmap);
DeleteDC(dc);
returnfalse;
}
SetBkColor(dc,crTransparent);
BitBlt(maskDC,0,0,nWidthSrc,nHeightSrc,dc,0,0,SRCINVERT);
SetBkColor(dc,RGB(0,0,0));
SetTextColor(dc,RGB(255,255,255));
BitBlt(dc,0,0,nWidthSrc,nHeightSrc,maskDC,0,0,SRCAND);
HDCnewMaskDC=CreateCompatibleDC(NULL);
HBITMAPnewMask;
newMask=CreateBitmap(nWidthDest,nHeightDest,1,
GetDeviceCaps(newMaskDC,BITSPIXEL),NULL);
if(newMask==NULL)
{
SelectObject(dc,oldBitmap);
DeleteDC(dc);
SelectObject(maskDC,oldMask);
DeleteDC(maskDC);
DeleteDC(newMaskDC);
DeleteObject(bitmap);
DeleteObject(maskBitmap);
returnfalse;
}
SetStretchBltMode(newMaskDC,COLORONCOLOR);
HBITMAPoldNewMask=(HBITMAP)SelectObject(newMaskDC,newMask);
StretchBlt(newMaskDC,0,0,nWidthDest,nHeightDest,maskDC,0,0,
nWidthSrc,nHeightSrc,SRCCOPY);
SelectObject(maskDC,oldMask);
DeleteDC(maskDC);
DeleteObject(maskBitmap);
HDCnewImageDC=CreateCompatibleDC(NULL);
HBITMAPnewImage=CreateBitmap(nWidthDest,nHeightDest,1,
GetDeviceCaps(newMaskDC,BITSPIXEL),NULL);
if(newImage==NULL)
{
SelectObject(dc,oldBitmap);
DeleteDC(dc);
DeleteDC(newMaskDC);
DeleteObject(bitmap);
returnfalse;
}
HBITMAPoldNewImage=(HBITMAP)SelectObject(newImageDC,newImage);
StretchBlt(newImageDC,0,0,nWidthDest,nHeightDest,dc,0,0,nWidthSrc,
nHeightSrc,SRCCOPY);
SelectObject(dc,oldBitmap);
DeleteDC(dc);
DeleteObject(bitmap);
BitBlt(dcDest,nXOriginDest,nYOriginDest,nWidthDest,nHeightDest,
newMaskDC,0,0,SRCAND);
BitBlt(dcDest,nXOriginDest,nYOriginDest,nWidthDest,nHeightDest,
newImageDC,0,0,SRCPAINT);
SelectObject(newImageDC,oldNewImage);
DeleteDC(newImageDC);
SelectObject(newMaskDC,oldNewMask);
DeleteDC(newMaskDC);
DeleteObject(newImage);
DeleteObject(newMask);
returntrue;
}
说明:
本文提供的TransparentBlt2函数旨在说明透明位图的显示原理,在Windows2000以上环境实际运用中建议使用现成的TransparentBlt函数来绘制透明位图。