加载图片的方法(II)

功能:

通过资源加载,和通过本地文件加载;

加载图片包括ico, bmp, png


方法(I)  使用Image,从资源加载

/****************************************************************************************************
//从GDI加载图片的方法(包括.bmp,.ico,.png)
* @param [inout] pImage 图片指针
* @param [in] lpType	资源类型,例如:IDI_ICON1,IDB_BMP1,IDB_PNG1
* @param [in] lpTyp		资源类型,例如:RT_BITMAP,RT_ICON,"PNG"(注意PNG图片没有系统定义)
****************************************************************************************************/
BOOL LoadImageFromResource(Image **pImage, DWORD dwResID, LPCSTR lpType)
{
	HGLOBAL	hGlobal = NULL;
	HRSRC	hSource = NULL;
	LPVOID	lpVoid = NULL;
	DWORD	dwSize = 0;
	BOOL	bRet = FALSE;

	//1..获取当前资源模块的句柄(均可)
	//HMODULE hInstance = AfxGetInstanceHandle();
	//HINSTANCE hInstance = GetModuleHandle(NULL);
	HINSTANCE hInstance = AfxGetResourceHandle();
	if (NULL == hInstance)
	{
		return FALSE;
	}

	//2..确定指定模块中指定类型和名称的资源所在位置
	//返回值:返回值为指向被指定资源信息块的句柄,为了获得这些资源,应将这个句柄传递给LoadResource函数.
	hSource = FindResource(hInstance, MAKEINTRESOURCE(dwResID), lpType);
	//hSource = FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(IDB_PNG1), "PNG");
	//hSource = FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ICON1), RT_ICON);
	//hSource = FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(IDB_BITMAP1), RT_BITMAP);
	if (NULL == hSource)
	{
		INT N = GetLastError();

		return FALSE;
	}

	//3..装载指定资源到全局存储器
	//参数1:处理包含资源的可执行文件的模块句柄,若hModule为NULL,系统从当前过程中的模块中装载资源
	//参数2:表示被装载资源的句柄,它必须由函数FindResource或FindResourceEx创建.
	//返回值:运行成功返回相关资源的数据的句柄,返回类型是向后兼容的HGLOBAL型,而不是因为函数返回一个全局存储块句柄,不要传递这个句柄给函数GlobalLock或GlobalFree.
	hGlobal = LoadResource(hInstance, hSource);
	if (NULL == hGlobal)
	{
		return FALSE;
	}

	//4..锁定内存中的指定资源,说白了就是返回资源在内存中的地址,不须解锁操作
	//参数表示被装载资源的句柄,由LoadResource()返回
	lpVoid = LockResource(hGlobal);
	if (NULL == lpVoid)
	{
		goto _Cleanup;
	}

	//5..返回指定资源的大小(参数1资源文件模块的句柄,参数2必须由FindResource或FindResourceEx来创建)
	dwSize = SizeofResource(hInstance, hSource);
	if (0 == dwResID)
	{
		goto _Cleanup;
	}

	//6..全局堆分配(GMEM_MOVEABLE:分配可移动的内存;可使用函数GlobalLock将返回句柄转换为一个指针)
	HGLOBAL hGlobal2 = GlobalAlloc(GHND, dwSize);
	if (NULL == hGlobal2)
	{
		goto _Cleanup;
	}

	//7..锁定内存中指定的内存块,并返回一个地址值,令其指向内存块的起始处
	//除非用GlobalUnlock()函数将内存块解锁,否则地址会一直保持有效
	LPVOID lpData = GlobalLock(hGlobal2);

	//8..拷贝数据
	memcpy_s(lpData, dwSize, (void *)hGlobal, dwSize);


	//9..从指定内存创建流对象
	//参数1是由GlobalAlloc分配的内存句柄;
	//参数2表示参数1所指定的内存在该流对象被释放后是否也自动释放,如果该参数设为FALSE,那么调用者必须显式的释放hGlobal,如果为TRUE,则hGlobal最终会自动释放.
	IStream* pStream = NULL;
	if (S_OK != CreateStreamOnHGlobal(hGlobal2, TRUE, &pStream))
	{
		GlobalFree(hGlobal2);
		goto _Cleanup;
	}

	//10..从指定的数据流创建Image
	*pImage = Gdiplus::Image::FromStream(pStream, FALSE);
	pStream->Release();

	//11..解除锁定的内存块
	//实际上是将内存对象的锁定计数器减一,用GlobalLock锁定的内存,一定要用GlobalUnlock解锁.
	GlobalUnlock(hGlobal2);

	//12..释放通过GlobalLock函数分配的内存(CreateStreamOnHGlobal中设为TRUE将自动释放hGlobal2)
	//GlobalFree(hGlobal2);

	bRet = TRUE;
	//int nBackWidth = (*pImage)->GetWidth();
	//int nBackHeight = (*pImage)->GetHeight();

_Cleanup:

	//解锁由LockResource()锁定的资源
	UnlockResource(hGlobal);

	//释放通过LoadResource函数分配的资源
	FreeResource(hGlobal);

	//开始绘图(需要放到OnEraseBkgnd()里实现)
	//CClientDC dc(this);
	//Graphics graphics(dc.m_hDC);//通过设备描述表句柄实例化一个 gdi+ Graphics 类成员
	//graphics.DrawImage(pImage, 0, 0, pImage->GetWidth(), pImage->GetHeight());

	return bRet;
}

方法(II) 使用CImage,从资源加载

/****************************************************************************************************
* 从GDI加载图片的法方
* @param [inout] pImage 图片指针
* @param [in] lpType	资源类型,例如:IDI_ICON1,IDB_BMP1,IDB_PNG1
* @param [in] lpTyp		资源类型,例如:RT_BITMAP,RT_ICON,"PNG"(注意PNG图片没有系统定义)
//注意: 调用处需要先CImage *pImage = new CImage
****************************************************************************************************/
BOOL LoadImageFromResource(CImage *pImage, DWORD dwResID, LPCSTR lpType)
{
	HGLOBAL	hGlobal = NULL;
	HRSRC	hSource = NULL;
	LPVOID	lpVoid = NULL;
	DWORD	dwSize = 0;
	BOOL	bRet = FALSE;

	//1..获取当前资源模块的句柄(均可)
	//HMODULE hInstance = AfxGetInstanceHandle();
	//HINSTANCE hInstance = GetModuleHandle(NULL);
	HINSTANCE hInstance = ::AfxGetResourceHandle();
	if (NULL == hInstance)
	{
		return FALSE;
	}

	//2..确定指定模块中指定类型和名称的资源所在位置
	//返回值:返回值为指向被指定资源信息块的句柄,为了获得这些资源,应将这个句柄传递给LoadResource函数.
	hSource = FindResource(hInstance, MAKEINTRESOURCE(dwResID), lpType);
	//hSource = FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_ICON1), RT_ICON);
	//hSource = FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(IDB_BITMAP1), RT_BITMAP);
	if (NULL == hSource)
	{
		return FALSE;
	}

	//3..装载指定资源到全局存储器
	//参数1:处理包含资源的可执行文件的模块句柄,若hModule为NULL,系统从当前过程中的模块中装载资源
	//参数2:表示被装载资源的句柄,它必须由函数FindResource或FindResourceEx创建.
	//返回值:运行成功返回相关资源的数据的句柄,返回类型是向后兼容的HGLOBAL型,而不是因为函数返回一个全局存储块句柄,不要传递这个句柄给函数GlobalLock或GlobalFree.
	hGlobal = LoadResource(hInstance, hSource);
	if (NULL == hGlobal)
	{
		return FALSE;
	}

	//4..锁定内存中的指定资源,说白了就是返回资源在内存中的地址,不须解锁操作
	//参数表示被装载资源的句柄,由LoadResource()返回
	lpVoid = LockResource(hGlobal);
	if (NULL == lpVoid)
	{
		goto _Cleanup;
	}

	//5..返回指定资源的大小(参数1资源文件模块的句柄,参数2必须由FindResource或FindResourceEx来创建)
	dwSize = SizeofResource(hInstance, hSource);
	if (0 == dwResID)
	{
		goto _Cleanup;
	}

	//6..全局堆分配(GMEM_MOVEABLE:分配可移动的内存;可使用函数GlobalLock将返回句柄转换为一个指针)
	HGLOBAL hGlobal2 = GlobalAlloc(GHND, dwSize);
	if (NULL == hGlobal2)
	{
		goto _Cleanup;
	}

	//7..锁定内存中指定的内存块,并返回一个地址值,令其指向内存块的起始处
	//除非用GlobalUnlock()函数将内存块解锁,否则地址会一直保持有效
	LPVOID lpData = GlobalLock(hGlobal2);

	//8..拷贝数据
	memcpy_s(lpData, dwSize, (void *)hGlobal, dwSize);

	//9..从指定内存创建流对象
	//参数1是由GlobalAlloc分配的内存句柄;
	//参数2表示参数1所指定的内存在该流对象被释放后是否也自动释放,如果该参数设为FALSE,那么调用者必须显式的释放hGlobal,如果为TRUE,则hGlobal最终会自动释放.
	IStream* pStream = NULL;
	if (S_OK != CreateStreamOnHGlobal(hGlobal2, TRUE, &pStream))
	{
		GlobalFree(hGlobal2);
		goto _Cleanup;
	}

	//10..从指定的数据流创建Image
	pImage->Load(pStream);
	pStream->Release();

	//11..解除锁定的内存块
	//实际上是将内存对象的锁定计数器减一,用GlobalLock锁定的内存,一定要用GlobalUnlock解锁.
	GlobalUnlock(hGlobal2);

	//12..释放通过GlobalLock函数分配的内存(CreateStreamOnHGlobal中设为TRUE将自动释放hGlobal2)
	//GlobalFree(hGlobal2);

	bRet = TRUE;
	//int nBackWidth = pImage->GetWidth();
	//int nBackHeight = pImage->GetHeight();

_Cleanup:

	//解锁由LockResource()锁定的资源
	UnlockResource(hGlobal);

	//释放通过LoadResource函数分配的资源
	FreeResource(hGlobal);

	return bRet;
}

方法(III)  使用Image,从本地文件加载

//从本地文件加载
BOOL LoadImageFromFile(Image **pImage, LPCSTR lpFile)
{
	CFile f;
	CFileException  e;
	if (!f.Open(lpFile, CFile::modeRead, &e))
	{
		return FALSE;
	}

	//分配全局内存
	DWORD dwSize = (DWORD)f.GetLength();
	HGLOBAL hMemBmp = GlobalAlloc(GHND, dwSize);
	if (NULL == hMemBmp)
	{
		return FALSE;
	}

	//锁定指定内存
	LPVOID pBmp = GlobalLock(hMemBmp);
	f.SeekToBegin();
	f.Read(pBmp, dwSize);

	//从指定内存创建流对象
	IStream* pStmBmp = NULL;
	if (S_OK == CreateStreamOnHGlobal(hMemBmp, FALSE, &pStmBmp))
	{
		//从指定的数据流创建Image
		*pImage = Image::FromStream(pStmBmp, FALSE);
		pStmBmp->Release();
	}

	//释放全局内存
	GlobalFree(hMemBmp);

	//开始绘图(需要放到OnEraseBkgnd()里实现)
	//CClientDC dc(this);
	//Graphics graphics(dc.m_hDC);//通过设备描述表句柄实例化一个 gdi+ Graphics 类成员
	//graphics.DrawImage(pImage, 0, 0, pImage->GetWidth(), pImage->GetHeight());

	return TRUE;
}


//从本地文件加载
BOOL LoadImageFromFile_V2(Image **pImage, LPCSTR lpFile)
{
	//从指定的数据流创建Image
	CT2CW wFile(lpFile);
	*pImage = Image::FromFile(wFile, FALSE);

	//开始绘图(需要放到OnEraseBkgnd()里实现)
	//CClientDC dc(this);
	//Graphics graphics(dc.m_hDC);//通过设备描述表句柄实例化一个 gdi+ Graphics 类成员
	//graphics.DrawImage(pImage, 0, 0, pImage->GetWidth(), pImage->GetHeight());

	return TRUE;
}

方法(IV) 视同Ciamge,从本地文件加载

//从本地文件加载
BOOL LoadImageFromFile(CImage *pImage, LPCSTR lpFile)
{
	CFile f;
	CFileException  e;
	if (!f.Open(lpFile, CFile::modeRead, &e))
	{
		return FALSE;
	}

	//分配全局内存
	DWORD dwSize = (DWORD)f.GetLength();
	HGLOBAL hMemBmp = GlobalAlloc(GHND, dwSize);
	if (NULL == hMemBmp)
	{
		return FALSE;
	}

	//锁定指定内存
	LPVOID pBmp = GlobalLock(hMemBmp);
	f.SeekToBegin();
	f.Read(pBmp, dwSize);

	//从指定内存创建流对象
	IStream* pStmBmp = NULL;
	if (S_OK == CreateStreamOnHGlobal(hMemBmp, FALSE, &pStmBmp))
	{
		//从指定的数据流创建Image
		pImage->Load(lpFile);
		pStmBmp->Release();
	}

	//释放全局内存
	GlobalFree(hMemBmp);

	//开始绘图(需要放到OnEraseBkgnd()里实现)
	//CClientDC dc(this);
	//Graphics graphics(dc.m_hDC);//通过设备描述表句柄实例化一个 gdi+ Graphics 类成员
	//graphics.DrawImage(pImage, 0, 0, pImage->GetWidth(), pImage->GetHeight());

	return TRUE;
}


//从本地文件加载,使用CImage类
BOOL LoadImageFromFile_V2(CImage *pImage, LPCSTR lpFile)
{
	pImage->Load(lpFile);

	return TRUE;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值