在上一篇文章中,我留下了一个谜题:如何使用透明背景绘制一张单色位图。今天我们来揭晓谜底。
丑话说前头,我不是一名 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》