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

标签 c++ c winapi bitmap gdi

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

SetBkColor(hdcSource, clrTransparency);
VERIFY(BitBlt(hdcMask, 0, 0, bm.bmWidth, bm.bmHeight, hdcSource, 0, 0, SRCCOPY));

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

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

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

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

对于 32 位彩色图像,我应该使用替代方法吗?覆盖上述技术的正常行为的 alpha channel 是否存在问题?

感谢您提供的任何帮助!

附录:我仍然无法找到一种技术来为我的 GDI+ 生成的源位图创建有效的单色位图。

我通过根本不生成单色位掩码而在某种程度上缓解了我的特殊问题,而是使用 TransparentBlt(),这似乎是正确的(但我不知道他们在内部做什么那是允许他们正确遮盖图像的任何不同)。

拥有一个非常好的、有效的函数可能会很有用:

HBITMAP CreateTransparencyMask(HDC hdc, HBITMAP hSource, COLORREF crTransparency);

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

最佳答案

如果有 alpha channel ,则无法执行此操作。 COLORREF 将高 8 位用于多种用途,包括指定低 3 字节是当前调色板的颜色表索引还是 RGB 三元组。因此,您不能在 clrTransparency 的高字节中指定除 0x00 以外的任何内容。

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

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

关于c++ - 如何为 32 位位图生成单色位掩码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3942781/

相关文章:

c++ - 构建不带/clr 选项的 dll

c - C 中 undefined reference 错误 外部汇编包含在 C 中

windows - 如何读出引导顺序?

c++ - WINAPI - 在不成为所有者的情况下关闭互斥锁

c++ - GCC constexpr 允许添加,但不允许使用地址进行按位或

C++/MFC/ATL 线程安全字符串读/写

c++ - 在 odeint 中使用 std::vector<Eigen::Vector3d> 作为状态类型

创建遍历目录的makefile

c - void * 赋值给 void **

c++ - 如何检测非事件 Win32 应用程序中的最小化?