使用BitBlt实现位图背景透明

原文链接:https://blog.csdn.net/linshaolie/article/details/21905739

我们先看一下 BitBlt 这个函数的原型:

BOOL BitBlt(int x, int y, int nWidth,nHeight, CDC* PsrcDC, int xSrc, int ySrc, DWORD dwRop);

参数介绍:

int x                               表示绘制位图目标左上角x坐标;

int y   表示绘制位图目标左上角y坐标;

int nWidth 表示绘制位图目标的区域宽度;

int nHeight                   表示绘制位图目标的区域高度;

CDC* pSrcDC            表示存储源位图的设备描述表;

int xSrc  表示源位图的左上角x坐标;

int ySrc  表示源位图的左上角y坐标;

DWORD dwRop          表示栅格运算标志;


dwRop的取值与值的描述如下表所示: 

描述

BLACKNESS

用调色板中索引为0的颜色(默认是黑色)填充目标矩形。

CAPTUREBLT

用调色板中索引为0的颜色(默认是黑色)填充目标矩形。

DSTINVERT 

将目标矩形反色。 

MERGECOPY

将源矩形中的颜色与当前目标设备环境选中的画刷通过逻辑与操作进行混合。

MERGEPAINT

将源矩形的颜色反色后与目标矩形的颜色通过逻辑或操作进行混合。

NOMIRRORBITMAP 

防止位图镜像翻转。

NOTSRCCOPY

源矩形反色复制到目标矩形。

NOTSRCERASE

将源矩形与目标矩形的颜色通过逻辑或操作混合后,再反色。

PATCOPY

将目标设备环境选中的画刷复制到目标位图。

PATINVERT

将目标设备环境选中的画刷与目标矩形中的颜色进行逻辑异或操作,复制到目标位图。

PATPAINT

将目标设备环境选中的画刷与源矩形中的颜色的反色进行逻辑或操作,其结果再与目标矩形的颜色进行逻辑或操作。

SRCAND

将源矩形与目标矩形的颜色进行逻辑与操作。

SRCCOPY

直接将源矩形拷贝到目标矩形,最常用的绘制位图属性。

SRCERASE

将目标矩形的反色与源矩形的颜色进行逻辑与操作。

SRCINVERT

将源矩形的颜色与目标矩形进行逻辑异或操作。

SRCPAINT

将源矩形的颜色与目标矩形进行逻辑或操作。

WHITENESS

用调色板中索引为1的颜色(默认是白色)填充目标矩形。

 

下面是整个实现过程:

1) 创建一张大小与需要绘制图像相同的位图作为“掩码”位图(maskBmp);

2) 将新创建的“掩码”位图存储至掩码位图的设备描述表(maskDC)中; 

3) 把内存设备描述表(memDC)的背景设置成“透明色”(SetBkColor(RGB(?, ?, ?))),即不需要显示的颜色;

4) 复制粘贴位图到“掩码”位图的设备描述表中,这个时候“掩码”位图设备描述表中存放的位图与位图设备描述表中的位图一样 (maskDC.BitBlt(……)) ,此时会进行掩码运算,体现掩码特性,即:与设置的背景设相同的为体现出白色,不同的体现出黑色。(下面会详细说明过程)。

5) 将内存DC里的图片与实际窗口背景颜色(设为白色)做逻辑异或(关键词:SRCINVERT)操作并在实际窗口中呈像;

6)将掩码DC的图与实际窗口背景颜色做逻辑与(关键字:SRCAND)操作,并在窗口中呈像;

7)重复第五步。

下面进行演示:

首先我们要贴上的图片是如下的一张图(即黑色背景红色方块):


我们要将它的背景透明,然后显示在窗口上。

说明:

图片宽度定义为       const int BMPWIDTH = 182,

        高度定义为       const int BMPHEIGHT =172;


第一步:创建一张掩码图,代码如下:

CBitmap maskBmp;
maskBmp.CreateBitmap(BMPWIDTH, BMPHEIGHT, 1, 1,NULL);

CreateBitmap函数说明:

参数1          nWidth:              指定位图宽度、单位为像素。

参数2          nHeight:             指定位图高度、单位为像素。

参数3          CPlanes:           指定该设备使用的颜色位面数目。

参数4          CBitsPerPel:    指定用来区分单个像素点颜色的位数(比特数目)。

参数5           LpvBits:             指向颜色数据数组指针。这些颜色数据用来设置矩形区域内像素的颜色。矩形区域中的每一扫描线必须是双字节的整数倍(不足部分以0填充)。如果该参数为NULL,将不对新生成的位图进行初始化。

 

第二步:将创建的掩码位图选进掩码位图的设备描述表中

如下:

CDC maskDC;                  //定义掩码DC
maskDC.CreateCompatibleDC(NULL);  //初始化设备DC
CBitmap *oldMaskBmp = maskDC.SelectObject(&maskBmp); //将掩码位图存入,并返回旧的位图

第三步:将内存设备描述表的背景色设置为透明色(即要实现透明的背景色,如本例子为黑色)

CBitmap bmpSquare; 	//定义一个CBitmap对象存储将要绘制的图(ID为IDC_SQUARE)
bmpSquare.LoadBitmap(IDC_SQUARE);             //加载位图
 
CDC memDC;  //创建内存DC
memDC.CreateCompatibleDC(NULL);               //初始化DC
CBitmap *oldMemBmp = memDC.SelectObject(&bmpSquare);//将位图存入内存DC中,并返回旧的位图
memDC.SetBkColor(RGB(0,0,0));               //将内存DC的背景色设置为黑色

第四步:将内存DC的位图在掩码DC中呈像

maskDC.BitBlt(0, 0, BMPWIDTH, BMPHEIGHT, &memDC, 0,0, SRCCOPY);

说明:

memDC中图为(黑色底红色方块):    + memDC背景色(全黑):     = 掩码计算后(白色底黑色方块):.  

 

现在maskDC中的图即为  :   ....  (白底黑方块)


 

第五步:将内存DC里的图片与实际窗口背景颜色(设为白色)做逻辑异或(关键词:SRCINVERT)操作并在实际窗口中呈像;如下:

CPanitDC dc(this);            //窗口DC
dc.BitBlt(0, 0, BMPWIDTH, BMPHEIGHT, &memDC, 0, 0,SRCINVERT);

说明:

memDC中图为(黑色底红色方块):  + 窗口背景色(全白):   =   异或操作后(白底蓝绿色方块):  .

逻辑说明: 

memDC背景(黑)其RGB为:       0 0 0 0 0 0 0 0,0 0 0 0 0 0 0 0,0 0 0 0 0 0 0 0

窗口背景(白)为:                         1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1

异或操作(相同为0不同为1):       1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1(白色)

------------------------------------------------------------------------------------------------------------------------------

memDC方块(红)为:                   1 1 1 1 1 1 1 1,0 0 0 0 0 0 0 0,0 0 0 0 0 0 0 0

窗口背景(白)为:                         1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1

异或操作结果:                                0 0 0 0 0 0 0 0,1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1(蓝绿色)

 

第六步:将掩码DC的图与实际窗口背景颜色做逻辑与(关键字:SRCAND)操作,并在窗口中呈像;如下:

dc.BitBlt(0, 0, BMPWIDTH, BMPHEIGHT, &maskDC, 0, 0,SRCAND);

说明:

maskDC中图为(白底黑方块):   +  窗口背景色(白底蓝绿色方块):   =    异或操作后(白底黑方块):  .

此时在绘图区域的背景图为  ....  .... (白色背景黑色方块)

逻辑说明:

maskDC背景(白)其RGB为:       1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1

窗口背景(白)为:                         1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1

与操作(1,1为1,其他为0):       1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1(白色)

---------------------------------------------------------------------------------------------------------------------------

maskDC方块(黑)为:                   0 0 0 0 0 0 0 0,0 0 0 0 0 0 0 0,0 0 0 0 0 0 0 0

窗口背景(蓝绿)为:                     0 0 0 0 0 0 0 0,1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1

逻辑与操作结果:                            0 0 0 0 0 0 0 0,0 0 0 0 0 0 0 0,0 0 0 0 0 0 0 0(黑色)

 

第七步:也是最后一步,重复第五步,也就是将内存DC里的图片与实际窗口背景颜色(设为白色)做逻辑异或(关键词:SRCINVERT)操作并在实际窗口中呈像;如下:

dc.BitBlt(0, 0, BMPWIDTH, BMPHEIGHT, &memDC, 0, 0,SRCINVERT);

说明:

memDC中图为(黑底红方块):  + 窗口背景色(白底黑方块):   =   异或操作后(白底红方块): .

逻辑说明: 

memDC背景(黑)其RGB为:       0 0 0 0 0 0 0 0,0 0 0 0 0 0 0 0,0 0 0 0 0 0 0 0

窗口背景(白)为:                         1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1

异或操作(相同为0不同为1):       1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 1(白色)

-------------------------------------------------------------------------------------------------------------------------------

memDC方块(红)为:                   1 1 1 1 1 1 1 1,0 0 0 0 0 0 0 0,0 0 0 0 0 0 0 0

窗口背景(黑)为:                         0 0 0 0 0 0 0 0,0 0 0 0 0 0 0 0,0 0 0 0 0 0 0 0

异或操作结果:                                1 1 1 1 1 1 1 1,0 0 0 0 0 0 0 0,0 0 0 0 0 0 0 0(红色)

 

此时的方块背景色白色即与整个窗口背景色相同,也就是说我们实现了透明显示位图哈。

最后,别忘记把改释放的资源释放!

如:

maskDC.SelectObject(oldMaskBmp);
memDC.SelectObject(oldMemBmp);
memDC.DeleteDC();

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个使用VB.NET执行位图复制操作的示例: ``` Imports System.Runtime.InteropServices Public Class Form1 Private Declare Auto Function BitBlt Lib "gdi32.dll" ( ByVal hdcDest As IntPtr, ByVal nXDest As Integer, ByVal nYDest As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hdcSrc As IntPtr, ByVal nXSrc As Integer, ByVal nYSrc As Integer, ByVal dwRop As Integer) As Boolean Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click ' 创建源位图 Dim bmpSrc As New Bitmap("D:\source.bmp") ' 创建目标位图 Dim bmpDest As New Bitmap(bmpSrc.Width, bmpSrc.Height) ' 获取源位图和目标位图的HDC Dim hdcSrc As IntPtr = Graphics.FromImage(bmpSrc).GetHdc() Dim hdcDest As IntPtr = Graphics.FromImage(bmpDest).GetHdc() ' 执行位图复制操作 BitBlt(hdcDest, 0, 0, bmpSrc.Width, bmpSrc.Height, hdcSrc, 0, 0, &HCC0020) ' 释放HDC Graphics.FromImage(bmpSrc).ReleaseHdc(hdcSrc) Graphics.FromImage(bmpDest).ReleaseHdc(hdcDest) ' 显示复制后的位图 PictureBox1.Image = bmpDest End Sub End Class ``` 在这个示例中,我们首先创建了一个源位图和一个空的目标位图,并获取它们的HDC。然后我们调用BitBlt函数,将源位图复制到目标位图中。最后,我们释放HDC并显示复制后的位图BitBlt函数的第一个参数是目标设备的HDC,第二个和第三个参数是目标矩形的左上角坐标,第四个和第五个参数是目标矩形的宽度和高度。第六个参数是源设备的HDC,第七个和第八个参数是源矩形的左上角坐标。最后一个参数指定了如何将源位图与目标位图组合。 在这个示例中,我们使用的组合模式是SRCCOPY,这意味着直接将源位图的像素复制到目标位图中。其他组合模式可以通过更改dwRop参数来实现不同的效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值