×

位图 单色 绘制 透明 背景

绘制一张透明背景的单色位图

jnlyseo998998 jnlyseo998998 发表于2023-03-17 14:50:03 浏览15 评论0

抢沙发发表评论

在上一篇文章中,我留下了一个谜题:如何使用透明背景绘制一张单色位图。今天我们来揭晓谜底。

丑话说前头,我不是一名 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》