GDI根据位图和透明度创建蒙版
Posted strive-sun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GDI根据位图和透明度创建蒙版相关的知识,希望对你有一定的参考价值。
#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"C:\Users\h2fM6d9.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; }
顺便说一句,这项技术是一种非常古老的实现方法,在GDI中引入的MaskBlt 可以取代它,它可以在一个调用中完成您想要的操作。但更进一步,MaskBlt在这一点上已经过时了。如果是想为游戏或类似游戏的游戏绘制精灵。实际上可能想要的是使用每个像素的Alpha加载PNG,并使用Alpha合成对其进行绘制。也可以使用GDI +或诸如FreeImage之类的开源图形库来实现。
以上是关于GDI根据位图和透明度创建蒙版的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 Bitmap::GetHBITMAP 将位图转换为带有 alpha 的 HBITMAP?