gpt4 book ai didi

c - 从位图和透明度颜色创建蒙版-Windows GDI

转载 作者:行者123 更新时间:2023-12-03 11:09:31 25 4
gpt4 key购买 nike

这是我过去两天尝试调试的代码:

#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))的图像:

这是图像 mask (分别是预期结果和实际结果(从左到右)):



此处引用: theForger’s Win32 API Programming Tutorial - Transparent Bitmaps

最佳答案

该代码可以正常工作,尽管它并没有完全按照您的想象做。如果没有看到任何输出,则说明此功能的外部原因是什么。

该代码的作用是设置两个位图,以供一种旧的Win32技术使用,以绘制一个 Sprite ,其中您使用不同的光栅操作代码对BitBlt进行两次调用,一个调用一个蒙版,另一个绘制该 Sprite ,以使 Sprite 的背景将不会被绘制。请注意,它既在创建掩码,也在更改源位图。 (“const HBITMAP bitmapHandle”中的“const”实际上并没有做任何事情。位图句柄就像资源ID一样,指的是Windows所管理的位图,而C++对此一无所知。如果您查看代码,最终的BitBlit将变为源位图,而不是掩码。该调用的作用是使源位图中的键色变黑,这是使用rop代码和两次blit绘制sprite所必需的。

顺便说一句,这项技术是一种非常古老的实现方法,在将MaskBlt引入API之前,该方法将在一次调用中完成您想做的事情。但更进一步,MaskBlt在这一点上已经过时了。您可能想为游戏或类似游戏的游戏绘制 Sprite 。几乎可以肯定,您真正想要的是使用每个像素的Alpha加载PNG,并使用Alpha合成对其进行绘制。您可以使用GDI+或开放源代码图形库(例如FreeImage)来执行此操作。

在下面的任何情况下,最少的代码都会演示此掩码代码的实际工作原理。只需更改以下来源,即可使“D:\test\hex_badge.bmp”成为您在问题中具有该六角形位图的位置的路径。

#include <windows.h>

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

HBITMAP g_bmp;
HBITMAP g_bmpMask;

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);

// 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).
SelectObject(bitmapGraphicsDeviceContext, bitmapHandle);
SelectObject(bitmapMaskGraphicsDeviceContext, 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);

// Clean-up
DeleteDC(bitmapGraphicsDeviceContext);
DeleteDC(bitmapMaskGraphicsDeviceContext);

// Voila!
return bitmapMaskHandle;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{

MSG msg = { 0 };
WNDCLASS wc = { 0 };
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
wc.lpszClassName = L"minwindowsapp";

g_bmp = (HBITMAP)LoadImage(hInstance, L"D:\\test\\hex_badge.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
g_bmpMask = createImageMask(g_bmp, RGB(255, 0, 0));

if (!RegisterClass(&wc))
return 1;

if (!CreateWindow(wc.lpszClassName,
L"Minimal Windows Application",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0, 0, 640, 480, 0, 0, hInstance, NULL))
return 2;

while (GetMessage(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}

LRESULT HandleWmPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;

HDC hdcScr = GetDC(NULL);
HDC hdcBmp = CreateCompatibleDC(hdcScr);
HBITMAP hbmOld = (HBITMAP)SelectObject(hdcBmp, g_bmp);

HDC hdcMask = CreateCompatibleDC(hdcScr);
HBITMAP hbmOldMask = (HBITMAP) SelectObject(hdcMask, g_bmpMask );

HDC hdc = BeginPaint(hWnd, &ps);
BitBlt(hdc, 0, 0, 184, 184, hdcMask, 0, 0, SRCCOPY);
BitBlt(hdc, 184, 0, 184, 184, hdcBmp, 0, 0, SRCCOPY);
EndPaint(hWnd, &ps);

SelectObject(hdcMask, hbmOldMask);
DeleteDC(hdcMask);

SelectObject(hdcBmp, hbmOld);
DeleteDC(hdcBmp);
ReleaseDC(NULL, hdcScr);

return 0;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

switch (message)
{
case WM_CLOSE:
PostQuitMessage(0);
break;

case WM_PAINT:
return HandleWmPaint(hWnd, wParam, lParam);

default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;

输出如下:

enter image description here

我不确定为什么您没有得到输出,但是很可能您要么没有成功加载位图,要么没有成功绘制到屏幕上。

关于c - 从位图和透明度颜色创建蒙版-Windows GDI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59422456/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com