透明位图的实现原理

MFC实现透明位图(附完整源码) 阅读详情

透明位图的绘制的实现原理

透明色的位图的绘制方法有多种,最简单的方法是调用现成的函数:TransparentBlt,也可以自己代码实现类似的功能,实现过程也有两种方式,一种是事先做一张掩码位图作为资源,另一种是动态利用代码生成掩码位图。这里我们将 Microsoft Windows 图形环境中用位图介绍动态生成掩码位图绘制具有透明区域位图的方法。

我想所谓的透明位图大家都应该明白,这里我也就不多说了。这里重要的是将透明位图的实现原理。

首先,找到两张将要合成的图,如下:(注意在这里用到的图只是供演示只用)

  初始图1  +    初始图2

将产生如下透明位图:

最终效果图

在具体和实现这种透明位图的效果之前,我想最好是先解释一些概念,这样下面可能会更好。

 

透明和不透明 透明象素是那些不会影响目标文件的象素,将看不见的象素;那么不透明象素就是将会出现在目标文件上覆盖原来位置的点的象素。

白色和黑色分别被假定为全1和全0的值

基本的操作BitBlt涉及到从源文件到目标文件的块传递,另外也有单色和彩色位图之间的转换,这里重要介绍单色和彩色位图之间的转换:从单色位图到彩色位图,单色位图中是1的地方需要先转换为彩色位图的背景色,全0的地方需要转换为前景色,然后在进行块间操作;从彩色位图到单色位图,彩色位图中所有和背景色一致的地方设置为全1,即白色,其余部分为0,黑色,然后操作,这一点很重要。

原文:When using BitBlt() to convert a monochrome bitmap to a color bitmap, GDI transforms all white bits (1) to the background color of the destination device context (DC). GDI transforms all black bits (0) to the text (or foreground) color of the destination DC. When using BitBlt() to convert a color bitmap to a monochrome bitmap, GDI sets to white (1) all pixels that match the background color of the source DC. All other bits are set to black (0).

光栅操作

BitBlt函数的最后一个参数指定了一个光栅操作(ROP),它明确定义了如何将源文件、目标文件和模式(由现在选出的刷子画笔定义)的位组合去形成一个目标文件。因为一个位图只是一个位值的集合,光栅操作(ROP)只是一个在位上操作的布尔等式。相应使用的设备,位图中的代表不同的事物。

在多色设备上,每个象素由一个位集合代表,他们要么形成一个指向颜色的索引,要么直接代表一种颜色。

在单色设备上,每个象素由一个位来代表,0表示黑色并且1代表白色。

对于所有的设备类型,光栅操作(ROP)只简单地在位展示上进行而不考虑他们的实际意义。

下面说明常用的集中ROP操作:

SRCCOPY

src

直接将源拷贝到目的

SRCAND

src AND dest

将目标文件中对应于源文件黑色区域的部分变黑,将对应于白色区域的部分留着不动

SRCINVERT

src XOR dest

将源插入到目标。二次使用时,将目标恢复到它原来的状态。在某种条件下可以代替SRCPAINT 操作  

SRCPAINT

src OR dest

将源文件中的非白色区域刷到目标文件中。源中的黑色区域不转换到目标中。

 

具体源代码如下:

/************************************************************************/

/* 自绘制透明位图的函数                                                 */

/************************************************************************/

BOOL DrawTransparentBmp(HDC hdcDest,      // 目标DC                                             

                                               int nXOriginDest,   // 目标X偏移                                       

                                               int nYOriginDest,   // 目标Y偏移                                        

                                               int nWidthDest,     // 目标宽度                                         

                                               int nHeightDest,    // 目标高度                                          

                                               HDC hdcSrc,         // DC                                              

                                               int nXOriginSrc,    // X起点                                            

                                               int nYOriginSrc,    // Y起点                                             

                                               int nWidthSrc,      // 源宽度                                              

                                               int nHeightSrc,     // 源高度                                      

                                               UINT crTransparent) // 透明色,COLORREF类型      

{

         if (nWidthDest < 1) return false;        

         if (nWidthSrc < 1) return false; 

         if (nHeightDest < 1) return false;       

         if (nHeightSrc < 1) return false;

        

         HDC hMaskDC,hImageDC;

 

         HBITMAP hMaskBitmap,hOldMaskBitmap;

         HBITMAP hImageBitmap,hOldImageBitmap;

 

         //创建mask DC 和临时存源文件的 DC

         hMaskDC = CreateCompatibleDC(hdcDest);

         hImageDC = CreateCompatibleDC(hdcDest);

 

         //创建mask 位图和image 兼容位图

         hMaskBitmap = CreateBitmap(nWidthSrc,nHeightSrc,1,1,NULL);   //单色位图

         hImageBitmap = CreateCompatibleBitmap(hdcDest,nWidthSrc,nHeightSrc);  //彩色位图

 

         //将位图选进DC

         hOldImageBitmap = (HBITMAP)SelectObject(hImageDC,hImageBitmap);

         hOldMaskBitmap = (HBITMAP)SelectObject(hMaskDC,hMaskBitmap);

 

         //src位图拷入临时的image 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);

 

         //此步生成掩码位图(mask bitmap),注意整个位图中白为1,黑为0

         //整个mask 位图中透明色的地方是白色,其他为黑色

         BitBlt(hMaskDC,0,0,nWidthSrc,nHeightSrc,hImageDC,nXOriginSrc,nYOriginSrc,SRCCOPY);

        

         SetBkColor(hdcDest,RGB(255,255,255));

         SetTextColor(hdcDest,RGB(0,0,0));

 

         BitBlt(hdcDest,nXOriginDest,nYOriginDest,nWidthSrc,nHeightDest,hImageDC,nXOriginSrc,nYOriginSrc,SRCINVERT);

         BitBlt(hdcDest,nXOriginDest,nYOriginDest,nWidthSrc,nHeightDest,hMaskDC,0,0,SRCAND);

         BitBlt(hdcDest,nXOriginDest,nYOriginDest,nWidthSrc,nHeightDest,hImageDC,nXOriginSrc,nYOriginSrc,SRCINVERT);

 

         //BitBlt(hdcDest,nXOriginDest,nYOriginDest,nWidthSrc,nHeightDest,hMaskDC,0,0,SRCAND);

         //BitBlt(hdcDest,nXOriginDest,nYOriginDest,nWidthSrc,nHeightDest,hImageDC,0,0,SRCPAINT);

        

         return true;       

}

 

解说:

// Set up destination for monochrome blt (only needed for monochrome
// mask). These are the default values and may not need to be
// changed. They should also be restored.
SetBkColor(hdcDest, RGB(255, 255, 255)); // 1s --> 0xFFFFFF
SetTextColor(hdcDest, RGB(0, 0, 0)); // 0s --> 0x000000

// Do the real work.
BitBlt(hdcDest, x, y, dx, dy, hdcSrc, x0, y0, SRCINVERT);
BitBlt(hdcDest, x, y, dx, dy, hdcMask, 0, 0, SRCAND);
BitBlt(hdcDest, x, y, dx, dy, hdcSrc, x0, y0, SRCINVERT);
被屏蔽的块传递处理中的三步操作如下:
第一步(带SRCINVERT的位块传递)将源位图异或到目标文件。这看起来有点意思,但第二步异或有把目标文件恢复成原始状态的效果。
第二步(带SRCAND的位块传递)是一个屏蔽操作。当屏蔽与目标文件相与,所有的透明象素都不会改变目标文件的象素,而不透明象素则直接把目标文件变为黑。现在目标文件中有了一个源文件的不透明部分给勾勒出来的图象,而它自身在透明部分中的异或图象。
第三步(带SRCINVERT的位块传递)与源文件异或送到目标文件。透明象素被恢复成源状态(两步异或就能做到),不透明象素则季节从源文件上复制。

透明位图实现 透明位图实现    我们在进行程序的界面设计时,常常希望将位图的关键部分,也既是图像的前景显示在界面上,而将位图的背景隐藏起来,将位图与界面很自然的融合在一起,本文介绍了透明位图的制作知识,并将透明位图在一个对话框中显示了出来。  一、实现方法  绘制"透明"位图是指绘制某一位图中除指定颜色外的其余部分,我们称这种颜色为"透明色"。通过将位图的背景色指定为" 阅读详情

相关推荐

透明位图的三种做法(转)

http://www.handytech.cn/main/ArticleShow_38.htm 在编程中我们都希望程序的界面能够尽可能的美观,因此可以在程序中使用位图资源。但是位图是一个矩形阵列,在显示时总是以矩形形式显示,有什么方法能够让位图也显示成为不规则式样呢(即位图

风云爱飞 1325

[源码和文档分享]使用BitBlt函数实现绘制透明位图

背景 在自己本科的时候,喜欢用 VC6.0 写一些小游戏来锻炼自己的编程水平。那些小游戏的游戏画面绘制都是使用Windows提供的GDI(图形设备接口)函数实现的,并没有调用现成的游戏引擎。所以,使得自己对GDI函数比较熟悉,能用它开发各式各样的小游戏。 其中,那些小游戏都会用到的一个关键技术,便是透明位图的绘制。现在,我把之前自己开发小游戏时...

qq_38474647的博客 393

透明位图的显示 SRCINVERT 掩码图

透明位图的显示 SRCINVERT 掩码图 (2012-07-17 15:04:13) 标签: it 分类: 软件_Software 掩码图是指一幅图,将需要保留的图象用一种颜色来表示,这种颜色一般选原图中没有的颜色,   然后将原图与掩码图做位与操作,可将原图中需要的图形扣出来。 1。将hdc中的图片贴到dctrans中,如果dctra

linshixina的专栏 3460

VC透明位图实现原理

<br />原文出处:http://blog.csdn.net/ThomasLiu83/archive/2005/08/01/443385.aspx<br />透明和不透明:<br />        透明象素是那些不会影响目标文件的象素,看不见的象素;不透明象素就是将会出现在目标文件上覆盖原来位置的点的象素。<br /><br />白色和黑色: 分别被假定为全1和全0的值<br /><br />基本的操作:BitBlt 涉及到从源文件到目标文件的块传递,另外也有单色和彩色位图 之间的转换。<br

DavinTanger的专栏 3826

VC++实现位图显示透明效果--实现原理

我们在进行程序的界面设计时,常常希望将位图的关键部分,也既是图像的前景显示在界面上,而将位图的背景隐藏起来,将位图与界面很自然的融合在一起,本文介绍了透明位图的制作知识,并将透明位图在一个对话框中显示了出来。本文所使用的原始位图及程序编译运行后的界面效果如下图所示: 图一、原始位图 图二、对话框界面上透明显示位图   一、实现方法  绘制"透明"位图是指绘制某一位图中除指定颜色...

SurpassLi的专栏 63

透明显示原理及其实现

图标显示原理   其实,Windows中随处可见的图标就是一个透明位图的典型实例。   图标是由两个单独的位图组成的。第一个位图是由黑色(颜色位全为0)背景与彩色图标图案组成的,该位图将与当前屏幕显示通过异或(XOR)操作结合起来,故称其为XOR位图。第二个位图是由白色(颜色位全为1)背景与黑色(颜色位全为0)图标图案组成的,该位图将与当前屏幕显示通过与(AND)操作结合起来,故称其为AND位

wanzhongyi的专栏 632

透明位图原理及代码

(半) 透明位图原理及代码 摘自http://www.bc99.cn/Article/ASPX/2007-3-27-cs/65D5KI8EJFGK.html>> 绘制半透明位图 有的时侯,我们希望显示一幅半透明位图。也就是说我们将一幅位图B显示到A位图上,又希望透过B位图看到A位图的一部分图像但不是全部。比如A位图是一幅曲线图,B是一幅提示位图,我们想在显示提示的同时看到已显示的曲线

Welcom to zougangx's blog 834

透明位图

摘要这篇文章讨论了在 Microsoft Windows 图形环境中用位图达到透明和屏蔽效果的几种方法,包括通过仿真和使用特殊的驱动器功能。包含其中的一个小样本应用程序 TRANSBLT 详细阐明了这篇文章讨论的大多数方法。介绍使用透明(TRANSPARENT)背景模式(用SetBrMode函数设置),一个应用程序就可以用透明文本,透明风格的线条和透明形状的刷子。令人悲伤的是,Micr

xjh_Love_paopao的专栏 1039

透明位图的显示

包含透明色的位图的绘制方法有多种,最简单的方法是调用现成的函数:TransparentBlt,也可以通过自己的代码实现类似 TransparentBlt的功能,实现过程也有两种形式,一种是事先做一张掩码位图,另一种是动态生成掩码位图。本文将介绍动态生成掩码位图绘制具有 透明区域位图的方法。一、TransparentBlt 函数的使用TransparentBlt 函数在Windows98/Win...

SurpassLi的专栏 38

(半) 透明位图原理及代码

<br /> <!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;}

hongya6088的专栏 1418

MFC透明位图(1)--BMP的实现

包含透明色的位图的绘制方法有多种,最简单的方法是调用现成的函数:TransparentBlt,也可以通过自己的代码实现类似TransparentBlt的功能,实现过程也有两种形式,一种是事先做一张掩码位图,另一种是动态生成掩码位图。本文将介绍动态生成掩码位图绘制具有透明区域位图的方法。   一、TransparentBlt 函数的使用   TransparentBlt 函数在W

xuhuan_wh的专栏 7582

透明色的位图

来自:http://www.vckbase.com/document/viewdoc/?id=532对原作者表示感谢!包含透明色的位图的绘制方法有多种,最简单的方法是调用现成的函数:TransparentBlt,也可以通过自己的代码实现类似TransparentBlt的功能,实现过程也有两种形式,一种是事先做一张掩码位图,另一种是动态生成掩码位图。本文将介绍动态生成掩码位图绘制具有透明区域

TQW4321的专栏 2418

MFC透明位图(1)--BMP的实现 .

透明位图的显示 作者:王骏 下载本文示例代码 包含透明色的位图的绘制方法有多种,最简单的方法是调用现成的函数:TransparentBlt,也可以通过自己的代码实现类似TransparentBlt的功能,实现过程也有两种形式,一种是事先做一张掩码位图,另一种是动态生成掩码位图。本文将介绍动态生成掩码位图绘制具有透明区域位图的方法。 一、TransparentBlt 函数的使用

MOKA 699

透明透明位图实现技术

绘制半透明位图 有的时侯,我们希望显示一幅半透明位图。也就是说我们将一幅位图B显示到A位图上,又希望透过B位图看到A位图的一部分图像但不是全部。比如A位图是一幅曲线图,B是一幅提示位图,我们想在显示提示的同时看到已显示的曲线,但不需要曲线的背景,就需有用到半透明位图。曲线看上去就象从B位图中渗透过来,其实半透明技术就是一种渗透技术,渗透公式我们可选用多种,在这里我们选用(A AND 0x...

编程资料大全 140

VC——位图透明显示

这里大部分内容摘自http://www.vckbase.com/document/viewdoc/?id=532 王俊的《透明位图的显示》。自己在看程序的过程中,遇到一些问题,所以进行少量的补充和说明。包含透明色的位图的绘制方法有多种,最简单的方法是调用现成的函数:TransparentBlt,也可以通过自己的代码实现类似TransparentBlt的功能,实现过程也有两种形式,一种是事先做一

qsycn的专栏 1944
上一篇: 系统进程
下一篇: google网络搜索技术
ThomasLiu83
博客等级 码龄22年 38粉丝 52原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值