程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> Direct2D開發:MFC下從資源文件中加載位圖,direct2dmfc

Direct2D開發:MFC下從資源文件中加載位圖,direct2dmfc

編輯:C++入門知識

Direct2D開發:MFC下從資源文件中加載位圖,direct2dmfc


轉載請注明出處:http://www.cnblogs.com/ye-ming

0X01 概述:

相對於GDI處理界面,Direct2D有得天獨厚的優勢,下圖就是Direct2D與GDI的效果對比,win32Direct2D開發有很多,但是到了mfc下,基本上就很少了,下的今天來講一下在資源文件下加載圖片的方法。

 

 

0X02 從資源加載位圖:

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

 

 

 

 

 

 

  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved