透明显示原理及其实现

原创 2006年05月24日 15:44:00

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

  当前屏幕显示与AND位图通过AND操作结合起来;
  当前屏幕显示与XOR位图通过XOR操作结合起来。

  大家知道,1与任何数值AND操作的结果将维持原数值,而0与任何数值AND操作的结果则是0,因此在步骤1中,AND位图中白色(1)与屏幕显示经过AND操作后被原色彩屏蔽,而黑色(0)则将原色彩屏蔽。步骤1结束后,屏幕上将留下一个黑色的图标图案。在随后的步骤2中,由于0与任何数值异或的结果都将是原数值,因此,XOR位图与屏幕显示经过异或操作后,位图和屏幕中的黑色部分都将被各自对应的彩色部分屏蔽。步骤2结束后,一个形状不规则的图标图案就出现在屏幕上了。这就是图标显示的原理。

       实现代码(VC)

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

BOOL DrawTransparentBmp(HDC hdc, HBITMAP hbmp, RECT &rect, COLORREF colorTrans)
{
 HDC dcImage, dcTrans, dcImage24;
 HBITMAP holdbmp24, hbmp24;
 HBITMAP holdbmp;
 HBITMAP hbmpTrans, holdbmpTrans;

 // 创建内存DC
 dcImage = CreateCompatibleDC(hdc);
 dcTrans = CreateCompatibleDC(hdc);
 dcImage24 = CreateCompatibleDC(hdc);

 if (dcImage == NULL || dcTrans == NULL || dcImage24 == NULL)
 // Error: can't create compatible dc
 return FALSE;
 // 获取图像属性
 BITMAP bmp;
 GetObject(hbmp, sizeof(bmp), &bmp);

 // 选择图片到目标DC中
 holdbmp = (HBITMAP)SelectObject(dcImage, hbmp);

 // 创建24位图
PBITMAPINFO lpBmpInfo;

 lpBmpInfo = (BITMAPINFO*) new BYTE[sizeof(BITMAPINFOHEADER)];

 lpBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
 lpBmpInfo->bmiHeader.biPlanes = 1;
 lpBmpInfo->bmiHeader.biBitCount = 24;//nBitCount;
 lpBmpInfo->bmiHeader.biCompression = BI_RGB;
 lpBmpInfo->bmiHeader.biSizeImage = 0;
 lpBmpInfo->bmiHeader.biClrUsed = 0;

 lpBmpInfo->bmiHeader.biWidth = bmp.bmWidth;
 lpBmpInfo->bmiHeader.biHeight = bmp.bmHeight;

 HDC dc = CreateCompatibleDC(NULL);

 // 生成新图片
 LPVOID lpBits;
 hbmp24 =::CreateDIBSection(dc,lpBmpInfo,DIB_RGB_COLORS,
 &lpBits,NULL,0);

 DeleteDC(dc);
 delete lpBmpInfo;

 if (hbmp24 == NULL)
  // Error
  return FALSE;

 //将24位图片选择到位图DC

ldbmp24 = (HBITMAP)SelectObject(dcImage24, hbmp24);

 // 将原图绘制到24位图中
itBlt(dcImage24, 0, 0, bmp.bmWidth, bmp.bmHeight, dcImage, 0, 0, SRCCOPY);

 // 创建Mask图
 hbmpTrans = CreateBitmap(bmp.bmWidth, bmp.bmHeight, 1, 1, NULL);
 if (hbmpTrans == NULL)
  // Error
  return FALSE;

 // 选择Mask图到dcTrans中
 holdbmpTrans = (HBITMAP)SelectObject(dcTrans, hbmpTrans);

 // 创建掩码图像(基于指定的颜色),即AND Mask图
ORREF oldbkcolor = SetBkColor(dcImage24, colorTrans);
 BitBlt(dcTrans, 0, 0, bmp.bmWidth, bmp.bmHeight, dcImage24, 0, 0, SRCCOPY);

 SetBkColor(dcImage24, RGB(0,0,0));
 COLORREF oldtextcolor = SetTextColor(dcImage24, RGB(255,255,255));
 BitBlt(dcImage24, 0, 0, bmp.bmWidth, bmp.bmHeight, dcTrans, 0, 0, SRCAND);

 // 去除指定颜色
 COLORREF crOldBack, crOldText;
crOldBack = SetBkColor(hdc, RGB(255,255,255));
crOldText = SetTextColor(hdc, RGB(0,0,0));

 // 显示透明图
 StretchBlt(hdc, rect.left, rect.top, rect.right - rect.left,rect.bottom - rect.top,
 dcTrans, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCAND);
 StretchBlt(hdc, rect.left, rect.top, rect.right - rect.left,rect.bottom - rect.top,
 dcImage24, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCPAINT);

 // 恢复设置及其释放资源
 SelectObject(dcImage, holdbmp);

 SelectObject(dcImage24, holdbmp24);
 SelectObject(dcTrans, holdbmpTrans);

 DeleteObject(hbmp24);
 DeleteObject(hbmpTrans);

 SetBkColor(hdc, crOldBack);
 SetTextColor(hdc, crOldText);

 SetBkColor(dcImage24, oldbkcolor);
 SetTextColor(dcImage24, oldtextcolor);

 DeleteDC(dcImage);
 DeleteDC(dcImage24);
 DeleteDC(dcTrans);

 return TRUE;
}

图像透明显示原理及其实现.pdf

  • 2015年08月29日 17:08
  • 216KB
  • 下载

透明显示原理及其实现 [转]

透明显示原理及其实现 图标显示原理  其实,Windows中随处可见的图标就是一个透明位图的典型实例。  图标是由两个单独的位图组成的。第一个位图是由黑色(颜色位全为0)背景与彩色图标图案组成的,该位...

透明显示原理及其实现

图标显示原理   其实,Windows中随处可见的图标就是一个透明位图的典型实例。   图标是由两个单独的位图组成的。第一个位图是由黑色(颜色位全为0)背景与彩色图标图案组成的,该位图将与当前屏幕...

VC透明位图的实现原理

原文出处:http://blog.csdn.net/ThomasLiu83/archive/2005/08/01/443385.aspx透明和不透明:        透明象素是那些不会影响目标文件...

Winform重写CreateParams实现控件的透明显示(Panel为例)

前阵子做GIS,要实现图层的显示效果,尝试将2个PictureBox叠在一起,将上面的一张图片的BackColor设为Color.Transparent,并不加载任何图片,希望能看见下面一张图片的内容...

VC实现半透明显示拖动图标

  • 2014年09月17日 21:12
  • 2.02MB
  • 下载

浅谈VC++实现透明位图的显示

  • 2011年07月10日 09:44
  • 166KB
  • 下载

【Visual C++】游戏开发笔记之十 基础动画显示(三) 透明动画的实现

"透明动画”是游戏中一定会用到的基本技巧,它通过图案的连续显示及图案本身背景的透明化处理,在背景图上产生出栩栩如生的动画效果。 看过之前笔记的朋友们应该知道,在笔记六里我们介绍了使位...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:透明显示原理及其实现
举报原因:
原因补充:

(最多只允许输入30个字)