分享
 
 
 

绘制半透明位图以及如何画透明位图

王朝vc·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

绘制半透明位图

有的时侯,我们希望显示一幅半透明的位图。也就是说我们将一幅位图B

显示到A位图上,又希望透过B位图看到A位图的一部分图像但不是全部。比如A位

图是一幅曲线图,B是一幅提示位图,我们想在显示提示的同时看到已显示的曲

线,但不需要曲线的背景

,就需有用到半透明位图。曲线看上去就象从B位图中渗

透过来,其实半透明技术就是一种渗透技术,渗透公式我们可选用多种,在这里

我们选用(A AND 0x7F)OR B。注意,白色不能产生渗透。

//参数说明:

//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实现的代码如下:

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实现的代码如下:

/*

这是一个用来画透明位图的函数

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);

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有