【发布时间】:2011-04-28 15:47:56
【问题描述】:
我在 OnInitDialog() 上尝试了以下代码,但没有显示任何内容。
m_staticLogo.SetBitmap(::LoadBitmap(NULL, MAKEINTRESOURCE(IDB_LOGO)));
其中m_staticLogo为静态图片控件,IDB_LOGO为png文件的资源ID。
【问题讨论】:
标签: c++ visual-studio mfc png
我在 OnInitDialog() 上尝试了以下代码,但没有显示任何内容。
m_staticLogo.SetBitmap(::LoadBitmap(NULL, MAKEINTRESOURCE(IDB_LOGO)));
其中m_staticLogo为静态图片控件,IDB_LOGO为png文件的资源ID。
【问题讨论】:
标签: c++ visual-studio mfc png
如您所见,::LoadBitmap(以及更新的::LoadImage)只处理.bmps。到目前为止,最简单的解决方案是将您的图像转换为.bmp。
如果图片有透明度,可以转换成32位的ARGB位图(这里有个叫AlphaConv的工具可以转换)。然后使用CImage 类LoadFromResource 方法加载图像。将CImage 传递给m_staticLogo.SetBitmap()。
但如果你真的需要它是.png,它可以做到。
方法 1(更简单的方法):使用 CImage::Load 从文件中加载 .png。将CImage 传递给m_staticLogo.SetBitmap()。
方法 2(更难的方法): 通过将资源加载到 COM IStream 并使用 CImage::Load 从资源中加载 .png。 (注意:CImage::LoadFromResource 看起来很诱人,但不适用于.png 图形)。要将资源放入 COM IStream,请参阅 this Codeproject article。请注意本文适用于Gdiplus::Bitmap,但关键部分是如何创建IStream,您应该能够适应CImage。最后,将CImage 传递给m_staticLogo.SetBitmap()。
编辑:更新为使用CImage,这比Gdiplus::Bitmap更容易。
【讨论】:
.png 转换为 32 位“ARGB”.bmp 来保持透明度。像 Paint.NET 这样的标准工具不会这样做。我已经用一个有效的工具更新了这篇文章。在 Visual Studio 中查看时可能看起来很奇怪,但呈现良好。这适用于单色背景。如果您有像照片这样的复杂背景,它将无法工作。
对于那些需要快速解决方案的人,这是一种使用 GDI+ 从资源中加载 png 文件的方法(来自此处的标准 GDI 的原始答案 - http://www.codeproject.com/Questions/377803/How-to-load-PNG-images-in-mfc):
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;
}
您可以使用“添加资源”命令将 png 文件添加为资源,然后在面板中选择“导入”。
【讨论】:
它支持的位图和图标。不确定.png。 或者,您可以尝试以下方法。
【讨论】:
如果您将 .png 图像文件转换为 .bmp 格式,您最终可以获得图像清晰度。因此,在对话框类中捕获 WM_PAINT 消息并使用
Graphics::DrawImage 方法
要获得此方法,请将您的项目与 gdiplus.lib 库链接。
【讨论】: