Direct2D开发:MFC下从资源文件中加载位图

转载请注明出处: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

  

赌上我的人生为梦想,即使是臭名远扬,也要我的名字响彻天堂
原文地址:https://www.cnblogs.com/ye-ming/p/6179729.html