如何添加透明的PNG作为工具栏图标?

我的目的是在Win32中创建一个包含透明图标的工具栏。我尝试使用以下代码创建一个带有自定义图像的按钮的简单工具栏:

class Regex

// Create the toolbar HWND hToolbar = CreateWindow(TOOLBARCLASsnAME,NULL,WS_CHILD | TBSTYLE_flaT | TBSTYLE_AUTOSIZE | TBSTYLE_LIST | CCS_BOTTOM,hwnd,ghInstance,// <-this is the HINSTANCE of the application NULL); // Set the font (this cannot be the problem) SendMessage(hToolbar,WM_setfONT,(WPARAM)hFontBold,static_cast<LPARAM>(MAKELONG(TRUE,0))); auto hImagelist = ImageList_Create(32,32,ILC_COLOR24 | ILC_MASK,1,0); HBITMAP bitmap = static_cast<HBITMAP>(LoadImage(ghInstance,/* ID_IMG_SPAWN is my custom resource -> */ MAKEINTRESOURCE(ID_IMG_SPAWN),IMAGE_BITMAP,NULL)); ImageList_AddMasked(hImagelist,bitmap,RGB(255,255,255) /* white is the transparent color */); SendMessage(hToolbar,TB_SEtimagelist,static_cast<WPARAM>(0),(LPARAM)hImagelist); 仅支持24位位图,这意味着没有用于透明度的alpha通道。但是,我可以通过ImageList_Create使用遮罩颜色来模拟透明效果。 (在这里,我将白色(ImageList_AddMasked)设置为蒙版颜色。)

这很好用,但是由于alpha通道中缺少粒度(每个像素是透明的或完全不透明的),因此以这种方式显示的图像极其清晰/呈锯齿状

我知道PNG格式可以解决此问题,因为它提供了真正的alpha通道。我知道Win32 ImageLists支持PNG格式,但是我不知道如何正确使用它。 (可以将PNG资源添加到Visual Studio资源中,但是我不知道如何从代码中使用它们。)

我找不到任何方法来使RGB(255,255)加载PNG。唯一受支持的类型是LoadImage IMAGE_BITMAPIMAGE_CURSOR。我将资源(IMAGE_ICON更改为PNG文件,并尝试了这三种类型中的每一种,但所有结果仅显示为空白:

如何添加透明的PNG作为工具栏图标?

有人可以帮我吗?如何使用ID_IMG_SPAWN加载透明的PNG并将其用作工具栏图像?

johnny_zhengyi 回答:如何添加透明的PNG作为工具栏图标?

  

ImageList_Create仅支持24位位图,这意味着没有用于透明度的Alpha通道。

不,那是错误的。 ImageList_Create 也支持32位位图

由于您打算在Win32中创建一个包含透明图标的工具栏,因此根本不需要加载PNG。如果您需要PNG,则可能必须按照@barmak的说明使用GdiPlus。

32位位图具有8位用于ALPHA。使用32位位图可以产生与PNG相同的效果。


执行这些操作时,您说按钮图像显示为空白:

  • ILC_COLOR24更改为ILC_COLOR32

  • ID_IMG_SPAWN的资源更改为32位位图


实际上要正确显示32位位图,您必须:

  • ILC_COLOR24更改为ILC_COLOR32

  • ID_IMG_SPAWN的资源更改为具有预乘alpha的32位位图

  • 在加载时为位图创建DIB部分

(Win32的格式要求非常严格)


问:如何为位图创建DIB部分?

A:在LR_CREATEDIBSECTION的最后一个参数中指定LoadImage

说明:

  

LoadImage((HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),MAKEINTRESOURCE(ID_IMG_SPAWN),IMAGE_BITMAP,32,NULL)

这是LoadImage函数的代码。请参见MSDN document of LoadImage,创建DIB部分,您所需要做的就是在LR_CREATEDIBSECTION的最后一个参数中指定LoadImage


问:如何获得具有预乘alpha的BMP?

A:Pixelformer可以帮助您将Alpha通道文件转换为预乘Alpha BMP。

步骤是

  1. 在Pixelformer中打开图像(任何格式),然后从菜单中选择“导出”

  1. 选择A8:R8:G8:B8(32bpp)和预乘Alpha ,然后单击“确定”。

然后,您可以保存您的BMP文件!将此BMP文件导入到Visual Studio资源中,替换以前的24位BMP。


然后,您不再需要使用ImageList_AddMasked(使图像更清晰),因为您的32位BMP中已经具有可识别的ALPHA。因此,直接使用ImageList_Add

好的,在上面解释了这些操作之后,您的代码应该是这样的:

// Create the toolbar
HWND hToolbar = CreateWindow(TOOLBARCLASSNAME,NULL,WS_CHILD | TBSTYLE_FLAT | TBSTYLE_AUTOSIZE | TBSTYLE_LIST | CCS_BOTTOM,hwnd,ghInstance,NULL);

// Set the font (this cannot be the problem)
SendMessage(hToolbar,WM_SETFONT,(WPARAM)hFontBold,static_cast<LPARAM>(MAKELONG(TRUE,0)));

auto hImagelist =
ImageList_Create(32,ILC_COLOR32 /*DON'T NEED THE MASK. CHANGED TO ILC_COLOR32.*/,1,0);

HBITMAP bitmap = static_cast<HBITMAP>(LoadImage((HINSTANCE)GetWindowLong(hwnd,LR_CREATEDIBSECTION  /*THIS IS IMPORTANT*/   ));

ImageList_Add(hImagelist,bitmap,NULL);
SendMessage(hToolbar,TB_SETIMAGELIST,static_cast<WPARAM>(0),(LPARAM)hImagelist);

如下所示,效果很好。


我上面回答的这些足以解决这个问题。

有关DIB bitmapsPremultiplied Alpha的更多信息,请参见链接。

,

LoadImage在尝试加载PNG资源时将返回NULL

您可以将PNG资源添加为ICON。否则,请使用Windows Imaging Component或Gdiplus +加载png资源。

按如下方式读取PNG资源:

HBITMAP loadimage(HINSTANCE hinst,const wchar_t* name)
{
    HBITMAP hbitmap = NULL;
    ULONG_PTR token;
    Gdiplus::GdiplusStartupInput tmp;
    Gdiplus::GdiplusStartup(&token,&tmp,NULL);
    if(auto hres = FindResource(hinst,name,RT_RCDATA))
        if(auto size = SizeofResource(hinst,hres))
            if(auto data = LockResource(LoadResource(hinst,hres)))
                if(auto stream = SHCreateMemStream((BYTE*)data,size))
                {
                    Gdiplus::Bitmap bmp(stream);
                    stream->Release();
                    bmp.GetHBITMAP(Gdiplus::Color::Transparent,&hbitmap);
                }
    Gdiplus::GdiplusShutdown(token);
    return hbitmap;
}

...
auto hbitmap = loadimage(ghinst,MAKEINTRESOURCE(ID_PNG1 ));
if(hbitmap)
{
    ImageList_AddMasked(himage,hbitmap,0);
    DeleteObject(hbitmap);
}

资源定义应如下所示:

ID_PNG1 RCDATA "file.png"
本文链接:https://www.f2er.com/3143828.html

大家都在问