如何为32位位图生成单色位掩码

Mor*_*hai 8 c c++ winapi gdi bitmap

在Win32下,通过执行以下操作,从位图生成单色位掩码以实现透明度使用是一种常见技术:

SetBkColor(hdcSource, clrTransparency);
VERIFY(BitBlt(hdcMask, 0, 0, bm.bmWidth, bm.bmHeight, hdcSource, 0, 0, SRCCOPY));
Run Code Online (Sandbox Code Playgroud)

这假定hdcSource是保存源图像的内存DC,而hdcMask是一个内存DC,它保存相同大小的单色位图(因此两者都是32x32,但源是4位颜色,而目标是1位单色).

但是,当源为32位颜色+ alpha时,这对我来说似乎失败了.我得到的是一个全黑的面具,而不是在hdcMask中获得单色位图.没有位设置为白色(1).而这适用于4位彩色光源.

我的搜索foo失败了,因为我似乎找不到任何对这个特定问题的引用.

我已经发现这确实是我的代码中的问题:即如果我使用16色(4位)的源位图,它可以工作; 如果我使用32位图像,它会产生全黑色蒙版.

在32位彩色图像的情况下,我应该使用另一种方法吗?alpha通道是否存在覆盖上述技术正常行为的问题?

感谢您提供的任何帮助!

ADDENDUM:我仍然无法找到为我的GDI +生成的源位图创建有效单色位图的技术.

根本没有生成单色位掩码,我有点缓解了我的特殊问题,而是我正在使用TransparentBlt(),这似乎是正确的(但我不知道他们在内部做了什么,这是任何不同的允许他们正确掩盖图像).

拥有一个非常好的,有效的功能可能是有用的:

HBITMAP CreateTransparencyMask(HDC hdc, HBITMAP hSource, COLORREF crTransparency);
Run Code Online (Sandbox Code Playgroud)

无论hSource的颜色深度如何,它始终创建有效的透明蒙版.

想法?

Chr*_*cke 5

如果有 Alpha 通道则无法做到这一点。COLORREF 将前 8 位用于多种目的,包括指定较低的 3 个字节是否是当前调色板的颜色表索引或 RGB 三元组。因此,您不能在 clrTransparency 的高字节中指定除 0x00 之外的任何内容。

如果您有一个 Alpha 位图,那么对于仍然“不知道”Alpha 通道的 GDI,没有明智的方法来实际比较 24 位 BkColor 与位图中的 32 位像素。

我希望 GDI 将 32bpp 位图中的 Alpha 通道视为“保留”,并且仅成功比较保留通道为零的像素。也就是说,无论如何,你的蒙版颜色必须完全透明才有机会成功。(并且,如果您制作了合法的预乘位图,这意味着 RGV 值也将为零,而不是限制您对遮罩颜色的选择:P)