VC++如何将rc资源中的图片加载到MFC的CImage对象中(附源码)
Posted dvlinker
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VC++如何将rc资源中的图片加载到MFC的CImage对象中(附源码)相关的知识,希望对你有一定的参考价值。
MFC中提供了处理图片的CImage类,可以加载.bmp、.jpg、.png、.tif和.gif等多种图片,然后通过DC绘制到窗口上。
CImage类支持通过路径加载图片,也可以从rc资源中去加载图片文件,但从资源加载图片时,除了bitmap位图类型之外,处理的都比较复杂,需要调用FindResource、SizeofResource、LoadResource、GlobalAlloc、GlobalLock、CreateStreamOnHGlobal等一系列接口将rc资源中的图片加载内存中,然后再加载到CImage对象中。
对于png图片,考虑其像素中可能包含alpha透明通道,需要做个alpha预乘,因为CImage内部时调用API函数AlphaBlend去处理图片绘制的,AlphaBlend要求绘制前要做alpha通道预乘。
将rc资源中图片加载到CImage对象中的代码实现如下:
CImage* LoadCImage( UINT nID, LPCTSTR lpszType, HINSTANCE hInstance )
CImage* pImage = NULL;
// 如果是位图类型,可以直接调用LoadFromResource去加载
if( RT_BITMAP == lpszType )
pImage = new CImage();
pImage->LoadFromResource( hInstance, nID );
if ( !pImage->IsNull() )
return pImage;
else
WriteLog( _T("[LoadCImage]CImage::LoadFromResource失败") );
delete pImage;
pImage = NULL;
return NULL;
CUIString strLog;
HRSRC hRsrc = ::FindResource( hInstance, MAKEINTRESOURCE(nID), lpszType );
ASSERT( hRsrc != NULL );
if ( NULL == hRsrc )
WriteLog( _T("[LoadCImage]::FindResource失败") );
return NULL;
DWORD dwSize = ::SizeofResource( hInstance, hRsrc );
LPBYTE lpRsrc = (LPBYTE)::LoadResource( hInstance, hRsrc );
ASSERT( lpRsrc != NULL );
if ( NULL == hRsrc )
WriteLog( _T("[LoadCImage]::LoadResource失败") );
return NULL;
HGLOBAL hMem = ::GlobalAlloc( GMEM_FIXED, dwSize );
if ( NULL == hMem )
WriteLog( _T("[LoadCImage]::GlobalAlloc失败") );
::FreeResource( lpRsrc );
return NULL;
LPBYTE pMem = (LPBYTE)::GlobalLock( hMem );
if ( NULL == pMem )
WriteLog( _T("[LoadCImage]::GlobalLock失败") );
::GlobalUnlock( hMem );
::GlobalFree( hMem );
::FreeResource( lpRsrc );
return NULL;
memcpy( pMem, lpRsrc, dwSize );
IStream * pStream = NULL;
HRESULT hr = ::CreateStreamOnHGlobal( hMem, FALSE, &pStream );
if ( pStream != NULL && hr == S_OK )
pImage = new CImage();
HRESULT hrs = pImage->Load( pStream );
pStream->Release();
//释放
::GlobalUnlock( hMem );
::GlobalFree( hMem );
::FreeResource( lpRsrc );
if ( hrs == S_OK )
if ( pImage->GetBPP() == 32 )
for(int i = 0; i < pImage->GetWidth(); i++)
for(int j = 0; j < pImage->GetHeight(); j++)
// 获取像素对应位置的RGB值的起始地址,如果作为一个整数值,从二进制的
// 位构成来看,从高位到低位依次是alpha,b,g,r。如果从ARGB值的起始
// 地址开始按字节逐个访问,低位存放在低内存地址上,所以pucColor[0]到
// pucColor[3]依次是r,g,b,alpha,所以下面预乘的是pucColor[3]
unsigned char* pucColor = reinterpret_cast<unsigned char *>( pImage->GetPixelAddress(i , j) );
// CImage内部对带透明通道的图片的绘制,使用AlphaBlend来处理,AlphaBlend
// 需要对rgb颜色进行alpha通道值预乘
pucColor[0] = pucColor[0] * pucColor[3] / 255;
pucColor[1] = pucColor[1] * pucColor[3] / 255;
pucColor[2] = pucColor[2] * pucColor[3] / 255;
return pImage;
else
delete pImage;
pImage = NULL;
return NULL;
else
WriteLog( _T("[LoadCImage]::CreateStreamOnHGlobal失败") );
::GlobalUnlock( hMem );
::GlobalFree( hMem );
::FreeResource( lpRsrc );
return NULL;
以上是关于VC++如何将rc资源中的图片加载到MFC的CImage对象中(附源码)的主要内容,如果未能解决你的问题,请参考以下文章
在vc++6.0MFC中如何添加Icon的ID为IDI_CALENDAR,IDI_COMPOSE图片资源?
请问下面的图片左上方的两个按钮加中间竖线用vc++中的MFC怎么去实现?完成后,另赠100分。
VC++ MFC工程中中如何将一个工程的资源(如对话框)复制到另外一个工程