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工程中中如何将一个工程的资源(如对话框)复制到另外一个工程

mfc 加载图片资源怎么弄?给个程序最好附上说明。

MFC VC++:Picture Control 无法加载 PNG 图像

VC Dll 中的资源 使用