折叠屏|绘制一张透明背景的单色位图

折叠屏|绘制一张透明背景的单色位图

文章图片

折叠屏|绘制一张透明背景的单色位图

文章图片

折叠屏|绘制一张透明背景的单色位图

在上一篇文章中 , 我留下了一个谜题:如何使用透明背景绘制一张单色位图 。 今天我们来揭晓谜底 。
丑话说前头 , 我不是一名 GDI 方面的专家 , 所以 , 除了下面讲述的两种方法之外 , 可能还有我所不知道的更好的解决方案 。 为了演示透明背景的效果 , 我先将窗口的背景色设置成工作区颜色 。

方法1:采用 MaskBlt API
上面的方法所需要编写的代码量最少 , 但我个人觉得有些矫枉过正了 。 它使用一个所谓的四元光栅操作 , 就好像是三元一样 , 只是因为我不想额外再创建一个图案画刷 。 (光栅操作 0x00AA0029 实际上是一个空操作(NOP)运算符 , 它不对目标区域做任何操作 , 我并没有特别记住它 , 而是通过查阅文档知道的)
MAKEOP4 这个宏的意思是:对于蒙版中所有的白色像素 , 不执行任何操作(NOP) , 而对于每一个黑色像素 , 执行 SRCCOPY 操作 。
【折叠屏|绘制一张透明背景的单色位图】请注意 , 背景色一直都没有被使用 , 毕竟我们是准备绘制一个透明背景的位图 。 因此 , 我们可以直接删除掉设置和恢复 DC 背景色的相关代码 。
方法2:传统的二步式
这是传统的两步走方案 。 第一种方法通过将前景设置为黑色 , 将背景设置为白色 , 然后使用 SRCAND 来擦除即将被覆盖的像素 。 这具有将所有前景像素擦除为零的效果 , 同时保持背景完好无损 。 第二个blit做同样的事情 , 但使用SRCPAINT 。 这意味着背景像素需要被视为黑色 , 以便当它们与目标“或”时 , 目标像素保持不变 。 前景色像素获得所需的前景色 。
此方法可以通过否定第一个 blit 来缩短 , 反转前景和背景感 , 这样黑色就不必在背景颜色和文本颜色之间移动 。

这种缩短是否真的是一种整体改进很难说 。 某些显示驱动程序可能具有高度优化的 SRCAND 处理程序 , 而它们不太可能具有优化的0x00220326处理程序 。
(练习:为什么你不能反转第二个步骤 , 将其转换为MERGEPAINT?)
总结细枝末节 , 我的最爱!
最后Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一 , 里面有很多关于Windows的小知识 , 对于广大Windows平台开发者来说 , 确实十分有帮助 。
本文来自:《Drawing a monochrome bitmap with transparency》