你是否正在寻找关于alphablend的内容?让我把最简洁的东西奉献给你:
关于 alphablend 和 32bpp 的反锯齿图标
在早前的一篇文章中我曾经研究过带有 alpha 通道的图标,实际上 XP 系统已经开始支持这样的图标,也就是32 bpp(bits per pixel)的图标了。在本文最后给出的MSDN链接中可以介绍开发者如何创建 32 bpp 的图标,不过不幸的是,VS开发环境不支持编辑这样的图标,而且原生的Photoshop也不支持(尽管有ICO格式插件),只能借助其他的图标制作工具,同样不幸的是,其他图标制作工具我用的并不顺手(至少没有PS那样熟练),所以我只能借助 Photoshop 和图标制作工具两者同时使用,从而可以完成制作 32 bpp 图标。
(一)关于 alphablend;
alphablend 是提供 alpha 通道的贴图的 API 函数,即每个像素都带有一个独立的 alpha 值,去指定该像素在最终合成结果中占据的比例,其作用就相当于Photoshop中的图层蒙版。这是 Msimg32.dll 中提供的函数,因此我们要使用这个函数,用以下语句指定 lib 文件(或在项目属性中添加):
#pragma comment(lib, "Msimg32.lib")
这个函数是从一个 HDC 拷贝到另一个 HDC,选入DC的图片需要具有4个通道,即按照地址从低到高的顺序是B,G,R,A。在提供 alhpa通道的图片格式里比较常用的是PNG格式,在 .net 里,GDI+可以从PNG图片加载出一个位图,然后用 Graphics.DrawImage 就可以看到合成的效果了,使用起来是非常简单的。在 C++ 中的贴图则分为数种(BitBlt,StretchBlt,PlgBlt,MaskBlt,TransparentBlt,AlphaBlend ...),前面大部分都是完整像素的传送和位操作,要实现两个像素的 alpha 合成,显然要使用的是 alphablend,由于这个函数在调用前还有一个特殊要求(如果你没有注意到这个要求,则很可能会对调用结果感到困惑),它在MSDN中的位置比较隐晦,是在介绍其最后一个参数 BLENDFUNCTION 中的一个成员(AlphaFormat)的取值时提到的:
这个要求是: 在调用 AlhpaBlend 之前,图片的 alpha 通道必须先应用到 RGB 通道上(premultiplied alpha)。
在之前我的文章中已给出了对一个 CImage 对象应用 alpha 通道的代码。这里我们不继续给出他的代码,现在假设我把一个PNG存储为32bpp的BMP 位图,然后可以从文件加载或者添加到PE文件的资源里面。然后就可以使用 LoadImage 从文件加载或者用 LoadBitmap 从资源加载了,如果从文件加载,必须指定一个标志:LR_CREATEDIBSECTION。
假设从资源中加载了这个位图,我们可以用下面的代码,预先应用 alhpa 通道:
代码下图可直观的看到应用前和应用后的图片的区别,左侧是原始位图,其右侧是应用了Alpha通道后的位图,这就是在调用 alphablend 之前应该选入Src DC的位图。虽然我们可以在运行时再去应用 alpha 通道,但是假如图片是已经确定的话(例如添加到PE的资源),那么我们为什么不先把比较消耗精力的这一步事先做掉呢?

上面的代码中,加载位图以后,为了修改像素,我使用 GetDIBits 函数去获取像素数据的一个拷贝,为此需要提供一个HDC,如果不提供HDC,就无法得到位图的像素(这让我有点不理解,我只想得到DIB的数据而已,不关心设备,但是API一定要求提供HDC有点不合情理),所以这里先获取程序的主窗口的HDC,得到位图数据然后我们把 alhpa 通道数据应用到 RGB 通道上。显然这样处理以后,图片会比原来的“变暗”一些,图像中完全透明的部分在结果中将完全变成黑色,半透明的部分会有所变暗。这样处理的要求可能是 API 觉得这样它的计算量可以有所减少(实际上也没少到哪里去),因为RGB通道可以直接和背景色被加权后(1- alpha/255) 的结果做加法。
这样处理后的位图就可以选入DC,然后调用 AlhpaBlend 函数了。这个函数的参数列表几乎和 TransparentBlt 一致,所以如果你的代码中使用了 TransparentBlt 则前面的参数无须改动,只需注意这个函数最后一个参数是 BLENDFUNCTION,从名称看仿佛是混合函数,实际上它只是一个含有4个整数的结构体而已。这个参数的设置决定了如何合成。SourceConstantAlpha 提供了整体的 Alpha 值,相当于PS中的图层不透明度,它是作用于整体的。Alpha 通道则相当于PS中的蒙版,控制每个像素的参与合成比例,是的作用在每个像素上的。关于成员的设置可以参考MSDN。下面就是使用 AlhpaBlend 的代码:
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shenmilingyu/article-5750-1.html
@Mr_凡先生
请教授下课吧