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