如何显示具有透明背景的菜单位图 [英] How to show menu bitmaps with transparent background

查看:59
本文介绍了如何显示具有透明背景的菜单位图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用此代码:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆