在 Win32 中显示带 alpha 通道的 32 位图像
Displaying 32 bit image with alpha channel in Win32
截图:http://i.imgur.com/hbExq9N.jpg
您好,我正在尝试在静态控件上设置带有 alpha 通道的 png,但是透明像素总是填充白色或黑色。
图像是在静态控件之上还是仅绘制在主控件上并不重要window。
如果有什么想法欢迎反馈。
谢谢
抱歉,我应该先有 post 代码
//First try loading icon with transparency to static control or button:
//static control;
HWND hL;
HICON iStick;
case WM_CREATE:
iStick = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 0, 0, LR_LOADTRANSPARENT);
hL = CreateWindow(L"STATIC", NULL, WS_CHILD | WS_VISIBLE | SS_BITMAP/*SS_ICON*/, 193, 290, 32, 32, hwnd, NULL, hInst, NULL);
SendMessage(hL, STM_SETIMAGE, IMAGE_ICON, (LPARAM)iStick);
//SendMessage(hL, STM_SETICON, IMAGE_ICON, (LPARAM)iStick);
//Second try to draw on background 32bit bmp A8R8G8B8 :
PAINTSTRUCT ps;
HDC hdc;
RECT r;
static HDC membit;
static BITMAP bm;
case WM_CREATE:
SetWindowLong(hWnd, GWL_EXSTYLE, WS_EX_TOPMOST | WS_EX_LAYERED);
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE |SWP_NOSIZE);
SetLayeredWindowAttributes(hWnd, 0, (255 * 100) / 100, LWA_ALPHA);
hStick = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP15));
GetObject(hStick, sizeof(bm), &bm);
membit = CreateCompatibleDC(hdc);
SelectObject(membit, hStick);
ReleaseDC(hWnd, hdc);
case WM_CTLCOLOREDIT:
SetTextColor((HDC)wParam, RGB(65, 65, 65)); //
return 0;
//MakeStaticbackground transparent
case WM_CTLCOLORSTATIC:
SetBkMode((HDC)wParam, TRANSPARENT); //
SetTextColor((HDC)wParam, RGB(38, 205, 247)); //
return (BOOL)GetStockObject(NULL_BRUSH);
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &r);
FillRect(hdc, &r, hBrush);
SetBkMode(hdc, TRANSPARENT);
BLENDFUNCTION BlendFunction;
BlendFunction.AlphaFormat = AC_SRC_ALPHA;
BlendFunction.BlendFlags = 0;
BlendFunction.BlendOp = AC_SRC_OVER;
BlendFunction.SourceConstantAlpha = 255;
//BitBlt(hdc, 500, 280, bm.bmWidth, bm.bmHeight, membit, 0, 0, SRCCOPY);
AlphaBlend(hdc, 500, 280, bm.bmWidth, bm.bmHeight, membit, 0, 0, 32, 32, BlendFunction);
//TransparentBlt(hdc, 500, 300, 32, 32, membit, 32, 32, 32, 32, RGB(255, 255, 255));
EndPaint(hWnd, &ps);
break;
case WM_ERASEBKGND:
return (LRESULT)1;
还有更多我不记得了,但背景像素总是填充白色或黑色。
我认为您只想要透明度,而不是 alpha 通道。你需要 LWA_COLORKEY
而不是 LWA_ALPHA
SetLayeredWindowAttributes(hWnd, window_background_brush, 255, LWA_COLORKEY);
这会将 window_background_brush
替换为透明色。如果没有设置背景画笔,则需要设置,最好是白色。另外最好使用图标,否则最终会出现粗糙的边缘。这是绘制图标的示例代码:
HDC hDC = ::GetDC(m_hWnd);
HICON hicon = (HICON)LoadImage(NULL, "fullpath.ico", IMAGE_ICON, w, h, LR_LOADFROMFILE);
DrawIconEx(hDC, x, y, hicon, w, h, 0, NULL, DI_NORMAL);
DestroyIcon(hicon);
::ReleaseDC(m_hWnd, hDC);
截图:http://i.imgur.com/hbExq9N.jpg
您好,我正在尝试在静态控件上设置带有 alpha 通道的 png,但是透明像素总是填充白色或黑色。
图像是在静态控件之上还是仅绘制在主控件上并不重要window。
如果有什么想法欢迎反馈。
谢谢
抱歉,我应该先有 post 代码
//First try loading icon with transparency to static control or button:
//static control;
HWND hL;
HICON iStick;
case WM_CREATE:
iStick = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 0, 0, LR_LOADTRANSPARENT);
hL = CreateWindow(L"STATIC", NULL, WS_CHILD | WS_VISIBLE | SS_BITMAP/*SS_ICON*/, 193, 290, 32, 32, hwnd, NULL, hInst, NULL);
SendMessage(hL, STM_SETIMAGE, IMAGE_ICON, (LPARAM)iStick);
//SendMessage(hL, STM_SETICON, IMAGE_ICON, (LPARAM)iStick);
//Second try to draw on background 32bit bmp A8R8G8B8 :
PAINTSTRUCT ps;
HDC hdc;
RECT r;
static HDC membit;
static BITMAP bm;
case WM_CREATE:
SetWindowLong(hWnd, GWL_EXSTYLE, WS_EX_TOPMOST | WS_EX_LAYERED);
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE |SWP_NOSIZE);
SetLayeredWindowAttributes(hWnd, 0, (255 * 100) / 100, LWA_ALPHA);
hStick = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP15));
GetObject(hStick, sizeof(bm), &bm);
membit = CreateCompatibleDC(hdc);
SelectObject(membit, hStick);
ReleaseDC(hWnd, hdc);
case WM_CTLCOLOREDIT:
SetTextColor((HDC)wParam, RGB(65, 65, 65)); //
return 0;
//MakeStaticbackground transparent
case WM_CTLCOLORSTATIC:
SetBkMode((HDC)wParam, TRANSPARENT); //
SetTextColor((HDC)wParam, RGB(38, 205, 247)); //
return (BOOL)GetStockObject(NULL_BRUSH);
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &r);
FillRect(hdc, &r, hBrush);
SetBkMode(hdc, TRANSPARENT);
BLENDFUNCTION BlendFunction;
BlendFunction.AlphaFormat = AC_SRC_ALPHA;
BlendFunction.BlendFlags = 0;
BlendFunction.BlendOp = AC_SRC_OVER;
BlendFunction.SourceConstantAlpha = 255;
//BitBlt(hdc, 500, 280, bm.bmWidth, bm.bmHeight, membit, 0, 0, SRCCOPY);
AlphaBlend(hdc, 500, 280, bm.bmWidth, bm.bmHeight, membit, 0, 0, 32, 32, BlendFunction);
//TransparentBlt(hdc, 500, 300, 32, 32, membit, 32, 32, 32, 32, RGB(255, 255, 255));
EndPaint(hWnd, &ps);
break;
case WM_ERASEBKGND:
return (LRESULT)1;
还有更多我不记得了,但背景像素总是填充白色或黑色。
我认为您只想要透明度,而不是 alpha 通道。你需要 LWA_COLORKEY
而不是 LWA_ALPHA
SetLayeredWindowAttributes(hWnd, window_background_brush, 255, LWA_COLORKEY);
这会将 window_background_brush
替换为透明色。如果没有设置背景画笔,则需要设置,最好是白色。另外最好使用图标,否则最终会出现粗糙的边缘。这是绘制图标的示例代码:
HDC hDC = ::GetDC(m_hWnd);
HICON hicon = (HICON)LoadImage(NULL, "fullpath.ico", IMAGE_ICON, w, h, LR_LOADFROMFILE);
DrawIconEx(hDC, x, y, hicon, w, h, 0, NULL, DI_NORMAL);
DestroyIcon(hicon);
::ReleaseDC(m_hWnd, hDC);