轉載請注明出處: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格式的圖片資源進行加載。
