Fork me on GitHub

[Direct2D开发] 从资源加载位图

转载请注明出处:http://www.cnblogs.com/Ray1024

 

一、概述

Direct2D使用Windows图像处理组件 (WIC) 来加载位图。从文件加载位图的方法很简单,而且网上的教程也很多,相信大家都非常熟悉了。但是如果需要从资源加载位图,该怎么做呢?

从资源加载Direct2D位图的需求是很常见的,但是网上关于从资源加载位图的资料很少。折腾了很久终于找到了解决方法,贴到这里供大家参考。

 

二、从资源加载位图

1.在应用程序资源定义文件中定义资源。下面代码为resource.h中的资源id:

//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by D2DCreateBitmapFromResource.rc
//
#define IDB_PNG1                        101

此资源会在生成应用程序时添加到应用程序的资源文件中。

 

2.从应用程序资源文件加载图像。

HRESULT LoadResourceBitmap(
	ID2D1RenderTarget *pRenderTarget,
	IWICImagingFactory *pIWICFactory,
	PCWSTR resourceName,
	PCWSTR resourceType,
	UINT destinationWidth,
	UINT destinationHeight,
	ID2D1Bitmap **ppBitmap)
{
	IWICBitmapDecoder *pDecoder = NULL;
	IWICBitmapFrameDecode *pSource = NULL;
	IWICStream *pStream = NULL;
	IWICFormatConverter *pConverter = NULL;
	IWICBitmapScaler *pScaler = NULL;

	HRSRC imageResHandle = NULL;
	HGLOBAL imageResDataHandle = NULL;
	void *pImageFile = NULL;
	DWORD imageFileSize = 0;

	// Locate the resource.
	imageResHandle = FindResourceW(HINST_THISCOMPONENT, resourceName, resourceType);
	HRESULT hr = imageResHandle ? S_OK : E_FAIL;
	if (SUCCEEDED(hr))
	{
		// Load the resource.
		imageResDataHandle = LoadResource(HINST_THISCOMPONENT, imageResHandle);

		hr = imageResDataHandle ? S_OK : E_FAIL;
	}

 

3.锁定资源并计算图像的大小。

	if (SUCCEEDED(hr))
	{
		// Lock it to get a system memory pointer.
		pImageFile = LockResource(imageResDataHandle);

		hr = pImageFile ? S_OK : E_FAIL;
	}
	if (SUCCEEDED(hr))
	{
		// Calculate the size.
		imageFileSize = SizeofResource(HINST_THISCOMPONENT, imageResHandle);

		hr = imageFileSize ? S_OK : E_FAIL;
	}

 

4.使用 IWICImagingFactory::CreateStream 方法创建 IWICStream 对象。

	if (SUCCEEDED(hr))
	{
		// Create a WIC stream to map onto the memory.
		hr = pIWICFactory->CreateStream(&pStream);
	}
	if (SUCCEEDED(hr))
	{
		// Initialize the stream with the memory pointer and size.
		hr = pStream->InitializeFromMemory(
			reinterpret_cast<BYTE*>(pImageFile),
			imageFileSize
			);
	}

 

5.使用 IWICImagingFactory::CreateDecoderFromStream 方法创建 IWICBitmapDecoder。

	if (SUCCEEDED(hr))
	{
		// Create a decoder for the stream.
		hr = pIWICFactory->CreateDecoderFromStream(
			pStream,
			NULL,
			WICDecodeMetadataCacheOnLoad,
			&pDecoder
			);
	}

 

6.从图像中检索某一帧并将该帧存储在 IWICBitmapFrameDecode 对象中。

	if (SUCCEEDED(hr))
	{
		// Create the initial frame.
		hr = pDecoder->GetFrame(0, &pSource);
	}

 

7.必须先将图像转换为 32bppPBGRA 像素格式,然后 Direct2D 才能使用该图像。若要转换图像格式,请使用IWICImagingFactory::CreateFormatConverter 方法创IWICFormatConverter 对象,然后使用 IWICFormatConverter 对象的Initialize 方法执行转换。

	if (SUCCEEDED(hr))
	{
		// Convert the image format to 32bppPBGRA
		// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
		hr = pIWICFactory->CreateFormatConverter(&pConverter);
	}
	if (SUCCEEDED(hr))
	{

		hr = pConverter->Initialize(
			pSource,
			GUID_WICPixelFormat32bppPBGRA,
			WICBitmapDitherTypeNone,
			NULL,
			0.f,
			WICBitmapPaletteTypeMedianCut
			);
	}

 

8.最后,使用 CreateBitmapFromWicBitmap 方法创建 ID2D1Bitmap 对象,该对象可通过呈现器目标绘制并与其他 Direct2D 对象一起使用。

	if (SUCCEEDED(hr))
	{
		//create a Direct2D bitmap from the WIC bitmap.
		hr = pRenderTarget->CreateBitmapFromWicBitmap(
			pConverter,
			NULL,
			ppBitmap
			);

	}

	SafeRelease(&pDecoder);
	SafeRelease(&pSource);
	SafeRelease(&pStream);
	SafeRelease(&pConverter);
	SafeRelease(&pScaler);

	return hr;
}

 

绘制效果图如下:

本文中只列出了部分代码。有关完整代码,请点击此处下载,源码为Direct2DTests中的D2DCreateBitmapFromResource文件。

 

注意:

大家在使用此方法加载图片资源时,不要加载.bmp格式的图片,这样会导致加载失败,尽量使用.png或.jpg格式的图片资源进行加载。

 

posted @ 2016-11-29 09:50  江湖码客Mark  阅读(2997)  评论(1编辑  收藏  举报