C++ 如何将png资源加载到对话框的图片控件中?
我在OnInitDialog()上尝试了以下代码,但没有显示任何内容C++ 如何将png资源加载到对话框的图片控件中?,c++,visual-studio,mfc,png,C++,Visual Studio,Mfc,Png,我在OnInitDialog()上尝试了以下代码,但没有显示任何内容 m_staticLogo.SetBitmap(::LoadBitmap(NULL, MAKEINTRESOURCE(IDB_LOGO))); 其中m_staticLogo是静态图片控件,IDB_LOGO是png文件的资源ID。位图及其支持的图标。不太清楚png。 或者,您可以尝试以下方法 在MS Paint或其他查看器中打开png 然后从中复制图像部分 在MFC资源中创建资源 将复制的图像粘贴到新创建的资源 在LoadBit
m_staticLogo.SetBitmap(::LoadBitmap(NULL, MAKEINTRESOURCE(IDB_LOGO)));
其中m_staticLogo是静态图片控件,IDB_LOGO是png文件的资源ID。位图及其支持的图标。不太清楚png。 或者,您可以尝试以下方法
正如您所发现的,
::LoadBitmap
(以及较新的::LoadImage
)只处理.bmp
s。到目前为止,最简单的解决方案是将图像转换为.bmp
如果图像具有透明度,则可以将其转换为32位ARGB位图(这里有一个名为的工具,可以对其进行转换)。然后使用CImage
classLoadFromResource
方法加载图像。将CImage
传递给m\u staticLogo.SetBitmap()
但是如果你真的需要它是一个.png
,它是可以做到的
方法1(更简单的方法):使用CImage::Load
从文件加载.png
。将CImage
传递给m\u staticLogo.SetBitmap()
方法2(较难的方法):通过将资源加载到COMIStream
并使用CImage::Load
从资源加载.png
。(注意:CImage::LoadFromResource
看起来很吸引人,但不能与.png
图形配合使用)。要将资源放入COMIStream
,请参阅。注意:本文使用的是Gdiplus::Bitmap
,但关键部分是如何创建IStream
,您应该能够适应CImage
。最后,将CImage
传递到m\u staticLogo.SetBitmap()
编辑:更新为使用
CImage
,这比Gdiplus::Bitmap
更容易。如果将.png图像文件转换为.bmp格式,则可以获得清晰的图像。所以,在对话框类中捕获WM_PAINT消息并使用
Graphics::DrawImage方法
要获得此方法,请将您的项目链接到gdiplus.lib库。对于那些需要快速解决方案的人,这里有一种使用GDI+从资源中加载png文件的方法(这里是标准GDI的原始答案-):
您可以使用“添加资源”命令将png文件添加为资源,并在面板中选择“导入”。我将png文件转换为bmp,但问题是转换后图像的背景不再透明。有没有办法转换,但仍然保留透明的背景?方法1的作品,但我更愿意有在资源文件的图形。方法2对我来说太难了。您可以通过将
.png
转换为32位的“ARGB”.bmp
来保持透明度。像Paint.NET这样的标准工具无法做到这一点。我用一个有效的工具更新了这篇文章。在VisualStudio中查看时,它可能看起来很奇怪,但渲染效果很好。这在单色背景下效果很好。如果你有一张照片这样复杂的背景,它就不起作用了。你能举一个调用LoadBitmapFromPNG()的正确方法的例子吗?很简单,只需使用:Bitmap*pBitmap=0;LoadBitmapFromPNG(IDB\u PNG\u您的资源\u ID和pBitmap);其中Bitmap*是GDI+位图类,IDB_PNG_YOUR_RESOURCE_ID是指向位图的资源的ID。
bool GdiPlusUtils::LoadBitmapFromPNG(UINT uResourceID,
Bitmap** ppBitmapOut, HINSTANCE hInstance /*= NULL*/)
{
bool bRet = false;
if (!hInstance)
hInstance = AfxGetInstanceHandle();
HRSRC hResourceHandle = ::FindResource(
hInstance, MAKEINTRESOURCE(uResourceID), L"PNG");
if (0 == hResourceHandle)
{
return bRet;
}
DWORD nImageSize = ::SizeofResource(hInstance, hResourceHandle);
if (0 == nImageSize)
{
return bRet;
}
HGLOBAL hResourceInstance = ::LoadResource(hInstance, hResourceHandle);
if (0 == hResourceInstance)
{
return bRet;
}
const void* pResourceData = ::LockResource(hResourceInstance);
if (0 == pResourceData)
{
FreeResource(hResourceInstance);
return bRet;
}
HGLOBAL hBuffer = ::GlobalAlloc(GMEM_MOVEABLE, nImageSize);
if (0 == hBuffer)
{
FreeResource(hResourceInstance);
return bRet;
}
void* pBuffer = ::GlobalLock(hBuffer);
if (0 != pBuffer)
{
CopyMemory(pBuffer, pResourceData, nImageSize);
IStream* pStream = 0;
if (S_OK == ::CreateStreamOnHGlobal(hBuffer, FALSE, &pStream))
{
*ppBitmapOut = new Bitmap(pStream);
pStream->Release();
bRet = true;
}
::GlobalUnlock(hBuffer);
}
::GlobalFree(hBuffer);
UnlockResource(hResourceInstance);
FreeResource(hResourceInstance);
return bRet;
}