zoukankan      html  css  js  c++  java
  • 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

      

    赌上我的人生为梦想,即使是臭名远扬,也要我的名字响彻天堂
  • 相关阅读:
    团队站立会议09
    团队站立会议08
    团队绩效
    团队站立会议07
    团队站立会议06
    团队站立会议05
    团队站立会议04
    团队站立会议03
    团队站立会议02
    反转链表
  • 原文地址:https://www.cnblogs.com/ye-ming/p/6179729.html
Copyright © 2011-2022 走看看