轉載請注明出處:http://www.cnblogs.com/ye-ming
相對於GDI處理界面,Direct2D有得天獨厚的優勢,下圖就是Direct2D與GDI的效果對比,win32Direct2D開發有很多,但是到了mfc下,基本上就很少了,下的今天來講一下在資源文件下加載圖片的方法。
1. 在資源文件下加載一張png或jpg。
#define IDB_PNG1 101
Bitmp不行,Bitmp是二進制文件,無法轉換,是否可以直接用有待考證。我遇到的問題和他一樣。http://stackoverflow.com/questions/9979848/iwicimagingfactorycreatedecoderfromstream-fails-error-message-message-is-no
2.添加Direct2D對象,第一篇文章提到,不在這裡重復http://www.cnblogs.com/ye-ming/articles/6170289.html
在OnInitDialog函數中添加代碼,沒有這一句AFX_WM_DRAW2D消息不執行。
this->EnableD2DSupport(TRUE);
3. 從應用程序資源文件中加載圖像
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; }
4.鎖定資源並計算圖像的大小。
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; }
5.使用 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 ); }
6.使用 IWICImagingFactory::CreateDecoderFromStream 方法創建 IWICBitmapDecoder。
if (SUCCEEDED(hr)) { // Create a decoder for the stream. hr = pIWICFactory->CreateDecoderFromStream( pStream, NULL, WICDecodeMetadataCacheOnLoad, &pDecoder ); }
7.從圖像中檢索某一幀並將該幀存儲在 IWICBitmapFrameDecode 對象中。
if (SUCCEEDED(hr)) { // Create the initial frame. hr = pDecoder->GetFrame(0, &pSource); }
8.必須先將圖像轉換為 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 ); }
9.最後,使用 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; }
10.創建工廠,開始初始化
HRESULT hr; hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pD2DFactory); if (m_pWICFactory == NULL && SUCCEEDED(hr)) { if (!SUCCEEDED( CoCreateInstance( CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&m_pWICFactory) ) )) return FALSE; } return hr;
11.創建位圖
HRESULT hr = S_OK; // 創建位圖 if (SUCCEEDED(hr)) { LoadResourceBitmap(pTarget, m_pWICFactory, MAKEINTRESOURCEW(IDB_PNG1), L"PNG", 0, 0, &m_pBitmap); } return hr;
12.開始畫圖
HRESULT hr; hr = CreateDeviceResources(pTarget); if (SUCCEEDED(hr) && !(pTarget->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED)) { pTarget->SetTransform(D2D1::Matrix3x2F::Identity()); pTarget->Clear(D2D1::ColorF(D2D1::ColorF::White)); pTarget->DrawBitmap( m_pBitmap, D2D1::RectF(0, 0, m_pBitmap->GetSize().width, m_pBitmap->GetSize().height)); } return hr;
13.在OnDraw2D()中創建Target並調用畫圖函數
CRect rect; GetClientRect(&rect); CHwndRenderTarget* m_pTarget = (CHwndRenderTarget*)lParam; ID2D1HwndRenderTarget* m_pITarget = m_pTarget->GetHwndRenderTarget(); if (m_pITarget) { CreateDeviceIndependentResources(); OnRender(m_pITarget); } return 0;
14.PS:
Direct2D高版本與低版本不兼容,本人寫的程序基於V7.x庫,V8.0以上庫不兼容(編程界的毒瘤)。
代碼下載:點擊下載
win32版本的代碼請參考:http://www.cnblogs.com/Ray1024/p/6104368.html