如何显示具有透明背景的菜单位图 [英] How to show menu bitmaps with transparent background
问题描述
我正在使用此代码:
m_bmpSwap.LoadBitmap(IDB_BITMAP2);pMnuPopup->SetMenuItemBitmaps(0, MF_BYPOSITION, &m_bmpSwap, &m_bmpSwap);
看起来像:
这只是一个测试图像:
如何让我的图片看起来好像有透明背景?
它是 24 位图像.
我见过
但是当我重新打开 WindowsBlinds 并再次显示时:
我自己是色盲,但我可以看出背景实际上与对话框背景相匹配,而不是菜单颜色背景.
这是我能做的最好的吗?
如何将 24 位或 32 位图像作为菜单位图?
添加 LR_LOADTRANSPARENT
标志以及 LR_LOADMAP3DCOLORS
这将适用于 8 位或 4 位图像(未使用 Windows 盲人测试)
<小时>或者您可以手动更改背景颜色
void swap_color(HBITMAP hbmp){如果(!hbmp)返回;HDC hdc = ::GetDC(HWND_DESKTOP);位图 bm;GetObject(hbmp, sizeof(bm), &bm);位图信息 bi = { 0 };bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);bi.bmiHeader.biWidth = bm.bmWidth;bi.bmiHeader.biHeight = bm.bmHeight;bi.bmiHeader.biPlanes = 1;bi.bmiHeader.biBitCount = 32;std::vector像素(bm.bmWidth * bm.bmHeight);GetDIBits(hdc, hbmp, 0, bm.bmHeight, &pixels[0], &bi, DIB_RGB_COLORS);//假设(0,0)处的颜色是背景色uint32_t color_old = 像素 [0];//这是新的背景颜色uint32_t bk = GetSysColor(COLOR_MENU);//用BGR交换RGBuint32_t color_new = RGB(GetBValue(bk), GetGValue(bk), GetRValue(bk));对于(自动和像素:像素)如果(像素== color_old)像素 = color_new;SetDIBits(hdc, hbmp, 0, bm.bmHeight, &pixels[0], &bi, DIB_RGB_COLORS);::ReleaseDC(HWND_DESKTOP, hdc);}
用法:
CBitmap bmp;bmp.LoadBitmap(IDB_BITMAP1);交换颜色(bmp);menu.SetMenuItemBitmaps(0, MF_BYPOSITION, &bmp, &bmp);
I am using this code:
m_bmpSwap.LoadBitmap(IDB_BITMAP2);
pMnuPopup->SetMenuItemBitmaps(0, MF_BYPOSITION, &m_bmpSwap, &m_bmpSwap);
It looks like:
It was only a test image:
How exactly do I get my image to look as if it has a transparent background?
It is 24 bit image.
I have seen this but I can't work it out.
I adjusted to a 8 bit image with 192/192/192 as the background and loaded like this:
HBITMAP hBmp;
hBmp = (HBITMAP)::LoadImage(AfxGetResourceHandle(),
MAKEINTRESOURCE(IDB_BITMAP2),
IMAGE_BITMAP,
0, 0, // cx,cy
LR_CREATEDIBSECTION | LR_LOADMAP3DCOLORS);
m_bmpSwap.Attach(hBmp);
pMnuPopup->SetMenuItemBitmaps(0, MF_BYPOSITION, &m_bmpSwap, &m_bmpSwap);
That seems better if I am not running WindowsBlinds:
But when I put WindowsBlinds back on and show it again:
I am colourblind myself, but I can tell that the background actually matches the dialog background and not the menu colour background.
Is this the best I can do?
Just how can I have a 24 bit or 32 bit image as a menu bitmap?
Add LR_LOADTRANSPARENT
flag as well as LR_LOADMAP3DCOLORS
This will work with 8-bit or 4-bit images (not tested with Windows blind)
Or you can manually change the background color
void swap_color(HBITMAP hbmp)
{
if(!hbmp)
return;
HDC hdc = ::GetDC(HWND_DESKTOP);
BITMAP bm;
GetObject(hbmp, sizeof(bm), &bm);
BITMAPINFO bi = { 0 };
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = bm.bmWidth;
bi.bmiHeader.biHeight = bm.bmHeight;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
std::vector<uint32_t> pixels(bm.bmWidth * bm.bmHeight);
GetDIBits(hdc, hbmp, 0, bm.bmHeight, &pixels[0], &bi, DIB_RGB_COLORS);
//assume that the color at (0,0) is the background color
uint32_t color_old = pixels[0];
//this is the new background color
uint32_t bk = GetSysColor(COLOR_MENU);
//swap RGB with BGR
uint32_t color_new = RGB(GetBValue(bk), GetGValue(bk), GetRValue(bk));
for (auto &pixel : pixels)
if(pixel == color_old)
pixel = color_new;
SetDIBits(hdc, hbmp, 0, bm.bmHeight, &pixels[0], &bi, DIB_RGB_COLORS);
::ReleaseDC(HWND_DESKTOP, hdc);
}
Usage:
CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP1);
swap_color(bmp);
menu.SetMenuItemBitmaps(0, MF_BYPOSITION, &bmp, &bmp);
这篇关于如何显示具有透明背景的菜单位图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!