【发布时间】:2020-04-12 19:15:33
【问题描述】:
这是我过去两天尝试调试的代码:
#include <windows.h>
HBITMAP createImageMask(HBITMAP bitmapHandle, const COLORREF transparencyColor) {
// For getting information about the bitmap's height and width in this context
BITMAP bitmap;
// Create the device contexts for the bitmap and its mask
HDC bitmapGraphicsDeviceContext = CreateCompatibleDC(NULL);
HDC bitmapMaskGraphicsDeviceContext = CreateCompatibleDC(NULL);
// For the device contexts to re-select the initial object they initialized with
// and de-select the bitmap and mask
HGDIOBJ bitmapDummyObject;
HGDIOBJ bitmapMaskDummyObject;
// The actual mask
HBITMAP bitmapMaskHandle;
// 1. Generate the mask.
GetObject(bitmapHandle, sizeof(BITMAP), &bitmap);
bitmapMaskHandle = CreateBitmap(bitmap.bmWidth, bitmap.bmHeight, 1, 1, NULL);
// 2. Setup the device context for the mask (and the bitmap)
// — also get the initial selected objects in the device contexts.
bitmapDummyObject = SelectObject(bitmapGraphicsDeviceContext, (HGDIOBJ) (HBITMAP) bitmapHandle);
bitmapMaskDummyObject = SelectObject(bitmapMaskGraphicsDeviceContext, (HGDIOBJ) (HBITMAP) bitmapMaskHandle);
// 3. Set the background color of the mask.
SetBkColor(bitmapGraphicsDeviceContext, transparencyColor);
// 4. Copy the bitmap to the mask and invert it so it blends with the background color.
BitBlt(bitmapMaskGraphicsDeviceContext, 0, 0, bitmap.bmWidth, bitmap.bmHeight, bitmapGraphicsDeviceContext, 0, 0, SRCCOPY);
BitBlt(bitmapGraphicsDeviceContext, 0, 0, bitmap.bmWidth, bitmap.bmHeight, bitmapMaskGraphicsDeviceContext, 0, 0, SRCINVERT);
// 5. Select the bitmaps out before deleting the device contexts to avoid any issues.
SelectObject(bitmapGraphicsDeviceContext, bitmapDummyObject);
SelectObject(bitmapMaskGraphicsDeviceContext, bitmapMaskDummyObject);
// Clean-up
DeleteDC(bitmapGraphicsDeviceContext);
DeleteDC(bitmapMaskGraphicsDeviceContext);
// Voila!
return bitmapMaskHandle;
}
它会创建一个位图句柄 (HBITMAP),并且不会产生任何错误(来自 GetLastError 函数)。
问题:它不会生成我应用到它的位图的单色版本,
而是创建一个仅填充黑色的位图。
那么代码是怎么回事,我做错了什么?
或者如何正确创建位图蒙版?
(如果可能,我正在尝试不使用 GDI+ 或其他库)
这是透明颜色为红色的图像 (RGB(255, 0, 0)):
这是图像掩码(预期结果和实际结果分别(从左到右)):
此处参考: theForger’s Win32 API Programming Tutorial - Transparent Bitmaps
【问题讨论】:
-
看来代码来自winprog.org/tutorial/transparency.html。您是否确保“调用此函数时未将位图选择到另一个 HDC”?
-
@GSerg:在我的代码中,位图是从一个文件中加载的,没有引用任何 HDC。然后在掩码之前使用函数
createImageMask创建掩码位图,然后将位图选择到 HDC 中。 -
bitmapMaskHandle在您删除该设备上下文时仍被选中到bitmapMaskGraphicsDeviceContext。我认为现代版本的 GDI 已经对此非常宽容,但从技术上讲,它违反了 API。您应该在删除 DC 之前选择它。另外,向我们展示绘画代码。您的蒙版是单色位图,尝试显示时很容易出错。 -
@AdrianMcCarthy:通过“在删除之前选择它退出...”你是指
SelectObject(hdc, myMask)然后SelectObject(hdc, someDummyObject)吗? -
SelectObject返回旧对象。保存它,然后在完成后重新选择它。