尝试这样的事情(请注意,我使用了"BINARY"
资源。也许它也可以与其他人一起使用,但不确定。此代码适用于32位位图,透明的PNG和JPEG):
#include <windows.h>
#include <gdiplus.h>
HBITMAP LoadBitmapFromResource(DWORD ResourceID,bool transparent = true)
{
HANDLE hGlobal = NULL;
ULONG_PTR GDIToken = 0;
Gdiplus::Image* Img = NULL;
Gdiplus::GdiplusStartupInput GDIStartInput = NULL;
Gdiplus::GdiplusStartup(&GDIToken,&GDIStartInput,NULL);
HRSRC hResource = FindResource(NULL,MAKEINTRESOURCE(ResourceID),"BINARY");
if (!hResource) {return NULL;}
HGLOBAL hFileResource = LoadResource(NULL,hResource);
if (!hFileResource) {return NULL;}
LPVOID lpFile = LockResource(hFileResource);
if (!lpFile) {return NULL;}
DWORD dwSize = SizeofResource(NULL,hResource);
if (!dwSize) {return NULL;}
void* data = LockResource(hFileResource);
if (!data) {return NULL;}
IStream* pStream = NULL;
hGlobal = GlobalAlloc(GMEM_FIXED,dwSize);
memcpy(hGlobal,data,dwSize);
UnlockResource(hFileResource);
FreeResource(hFileResource);
if (CreateStreamOnHGlobal(hGlobal,true,&pStream) == S_OK)
{
Img = new Gdiplus::Image(pStream,false);
pStream->Release();
GlobalFree(hGlobal);
hGlobal = NULL;
HBITMAP hBitmap = NULL;
static_cast<Gdiplus::Bitmap*>(Img)->GetHBITMAP(transparent ? Gdiplus::Color::Transparent : Gdiplus::Color(0,0),&hBitmap);
delete Img;
Gdiplus::GdiplusShutdown(GdiImage::GDIToken);
GDIStartInput = NULL;
GDIToken = 0;
return hBitmap;
}
GlobalFree(hGlobal);
hGlobal = NULL;
Gdiplus::GdiplusShutdown(GdiImage::GDIToken);
GDIStartInput = NULL;
GDIToken = 0;
return NULL;
}
您将必须链接到GDIPlus
。不断地为您加载的每个图像启动和关闭GDIPlus并不是很好,所以最好将其移动到某个位置。但是除此之外,一切都应该正常工作。
还有其他一些没有GDIPlus的方法,但是它可以发表很长的篇幅。
,
我了解到Visual Studio特此只能识别24位bmp。
不,那是错误的。 Visual Studio 支持Alpha预乘的32位位图。
32位位图具有8位用于ALPHA,可以产生平滑效果。
要正确显示32位位图,您必须:
(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。
步骤是
- 在Pixelformer中打开图像(任何格式),然后从菜单中选择“导出”
- 选择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位图?” “什么是预乘Alpha?”。这些是很深的话题。
要学习DIB bitmaps和Premultiplied Alpha,请参阅链接。
,
如果您使用的是Visual Studio 2010或更高版本(我想),则可以使用PNG文件。如here所述。
本文链接:https://www.f2er.com/3144483.html