图片区域透明

绘制半透明位图

有的时侯,我们希望显示一幅半透明的位图。也就是说我们将一幅位图b
显示到a位图上,又希望透过b位图看到a位图的一部分图像但不是全部。比如a位

图是一幅曲线图,b是一幅提示位图,我们想在显示提示的同时看到已显示的曲
线,但不需要曲线的背景,就需有用到半透明位图。曲线看上去就象从b位图中渗
透过来,其实半透明技术就是一种渗透技术,渗透公式我们可选用多种,在这里
我们选用(a and 0x7f)or b。注意,白色不能产生渗透。
C/C++ code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//参数说明:
//hdib -位图句柄
//ppal -位图调色板
//xdest -显示位图的左上角x坐标
//ydest -显示位图的左上角y坐标
void  drawsemitransparentbitmap(cdc *pdc,  int  nxdest,  int  nydest, hglobal hdib,cpalette *ppal)
bitmapinfo &bminfo = *(lpbitmapinfo)hdib ;
int  ncolors = bminfo.bmiheader.biclrused ? bminfo.bmiheader.biclrused :
1 << bminfo.bmiheader.bibitcount;
int  nwidth = bminfo.bmiheader.biwidth;
int  nheight = bminfo.bmiheader.biheight;
 
lpvoid lpdibbits = (lpvoid)(bminfo.bmicolors + ncolors);
cdc memdc;
memdc.createcompatibledc( pdc );
cbitmap bmp;
bmp.createcompatiblebitmap( pdc, nwidth, nheight );
cbitmap *poldbitmap = memdc.selectobject( &bmp );
if ( pdc->getdevicecaps(rastercaps) & rc_palette&&ncolors<256)
cpalette *poldmempalette = memdc.selectpalette(ppal,  false );
memdc.realizepalette();
::setdibitstodevice(memdc.m_hdc, 0, 0, nwidth, nheight, 0, 0, 0, nheight, lpdibbits, (lpbitmapinfo)hdib, dib_rgb_colors);
 
cdc maskdc;
cbitmap mbm;
maskdc.createcompatibledc(pdc);
mbm.createcompatiblebitmap(pdc, nwidth, nheight);
maskdc.selectobject(&mbm);
maskdc.fillsolidrect(crect(0, 0, nwidth, nheight), rgb(0x7f, 0x7f, 0x7f));
pdc->bitblt(nxdest, nydest, nwidth, nheight, &maskdc, 0, 0, srcand);
pdc->bitblt(nxdest, nydest, nwidth, nheight, &memdc, 0, 0, srcpaint);
memdc.selectobject(poldbitmap);
} 


如何画透明位图


  画透明位图通常的方法是使用遮罩。所谓遮罩就是一张黑白双色的位图,他和
要透明的位图是对应的,遮罩描述了位图中需要透明的部分,透明的部分是黑色的,
而不透明的是白色的,白色的部分就是透明的部分。
假设图a是要画的透明位图,图b是遮罩,图a上是一个大写字母a,字母是红色的,背
景是黑色的,图b背景是白色的,上面有一个黑色的字母a和图a的形状是一样的。
比如我们要在一张蓝天白云的背景上透明地画图a,就是只把红色的字母a画上去。我

们可以先将图b和背景进行与操作,再把图b和背景进行或操作就可以了。
用vc++ mfc实现的代码如下:
C/C++ code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void  cdemodlg::onpaint()
cpaintdc dc( this );
cbitmap bmpback,bmpa,bmpb,*poldback,*polda,*poldb;
bmpback.loadbitmap(idb_background);  // 载入背景图
bmpa.loadbitmap(idb_bitmapa);  //载入图a
bmpb.loadbitmap(idb_bitmapb);  //载入图b
cdc dcback,dca,dcb;  //声明三个内存dc用于画图
dcback.createcompatibledc(&dc);
dca.createcompatibledc(&dc);
dcb.createcompatibledc(&dc);  //把这三个内存dc创建成和paintdc兼容的dc
 
poldback=dcback.selectobject(&bmpback);
polda=dca.selectobject(&bmpa);
poldb=dcb.selectobject(&bmpb);  //把三个位图选入相应的dc
dc.bitblt(0,0,100,100,&dcback,0,0,srccopy);  //画背景
dc.bitblt(0,0,48,48,&dcb,0,0,srcand);  //用与的方式画遮罩图b
dc.bitblt(0,0,48,48,&dca,0,0,srcpaint);  //用或的方式画遮图a
dcback.selectobject(poldback);
dcback.selectobject(polda);
dcback.selectobject(poldb);  //从内存dc中删除位图

你会看到红色的字母a透明地画在背景上了。

用遮罩的方法必须事先做好遮罩,遮罩和位图大小一样等于多消耗一倍的资源,
比较浪费。还有一种画透明位图的方法,基本原理是一样的,只是不用事先做好
遮罩,根据需要动态生成遮罩,但是要求需要透明的位图必须指定一种透明色,
凡是这个透明色的地方则画成透明的。
用vc++ mfc实现的代码如下:
C/C++ code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/*
这是一个用来画透明位图的函数
cdc *pdc 需要画位图的cdc指针
uint idimage 位图资源id
crect &rect 指定位图在pdc中的位置
colorref rgbmask 位图的透明色
 
*/
void  drawtransparentbitmap(cdc *pdc, uint idimage,crect &rect, colorref rgbmask)
cdc imagedc,maskdc;
cbitmap image,*poldimage;
cbitmap maskbitmap,*poldmaskdcbitmap ;
image.loadbitmap(idimage);
imagedc.createcompatibledc(pdc);
poldimage=imagedc.selectobject(&image);
maskdc.createcompatibledc(pdc);
maskbitmap.createbitmap( rect.width(), rect.height(), 1, 1, null );
poldmaskdcbitmap = maskdc.selectobject( &maskbitmap );
imagedc.setbkcolor(rgbmask);
maskdc.bitblt( 0, 0, rect.width(), rect.height(), &imagedc, 0, 0, srccopy );
 
imagedc.setbkcolor(rgb(0,0,0));
imagedc.settextcolor(rgb(255,255,255));
imagedc.bitblt(0, 0, rect.width(), rect.height(), &maskdc, 0, 0, srcand);
pdc->bitblt(rect.left,rect.top,rect.width(), rect.height(), &maskdc, 0, 0, srcand);
pdc->bitblt(rect.left,rect.top,rect.width(), rect.height(), &imagedc, 0, 0,srcpaint);
maskdc.selectobject(poldmaskdcbitmap);
imagedc.selectobject(poldimage);
void  cdemodlg::onpaint()
cpaintdc dc( this );
cbitmap bmpback,*poldback,;
bmpback.loadbitmap(idb_background);
 
cdc dcback;
dcback.createcompatibledc(&dc);
poldback=dcback.selectobject(&bmpback);
dc.bitblt(0,0,100,100,&dcback,0,0,srccopy);
drawtransparentbitmap(&dc,idb_bitmapa,crect(0,0,48,48),rgb(192,192,0));
 
dcback.selectobject(poldback);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值