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

    // 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(, &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,

        .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", , , &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(, ,
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 ;

14.PS:

Direct2D高版本与低版本不兼容,本人写的程序基于V7.x库,V8.0以上库不兼容(编程界的毒瘤)。

代码下载:点击下载

win32版本的代码请参考:http://www.cnblogs.com/Ray1024/p/6104368.html

Direct2D开发:MFC下从资源文件中加载位图的更多相关文章

  1. 下载某资源文件并加载其中的所有Prefab到场景中

    using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary> / ...

  2. HTML页面处理以及资源文件的加载

    Javascript 异步加载详解 这篇文章很详细的介绍了HTML的页面处理以及资源文件的加载. 本文总结一下浏览器在 javascript 的加载方式. 关键词:异步加载(async loading ...

  3. C#动态编译代码,执行一个代码片段,或者从指定文件中加载某个接口的实现类

    在项目进行中有时候会需要配置一些复杂的表达式,在程序运行的时候执行表达式,根据结果执行相应的操作,简单写了一个类Expression,利用.net的动态编译技术实现,代码如下: public clas ...

  4. Django_在单独文件中加载Django环境临时调试

    创建Django环境后,每次在打印调试都需要基于项目有些麻烦. 如何在项目外的文件中加载项目环境进行便携的调试? 创建一个新的 orm.py import os if __name__ == '__m ...

  5. DirectUI界面编程(三)从XML文件中加载界面

    Duilib支持xml界面布局,使得界面设计与逻辑处理相分离,本节介绍如何从xml文件中加载界面元素. 我们需要以下几个步骤: 创建并初始化CPaintManagerUI对象. 创建CDialogBu ...

  6. 【python游戏编程之旅】第四篇---pygame中加载位图与常用的数学函数。

    本系列博客介绍以python+pygame库进行小游戏的开发.有写的不对之处还望各位海涵. 在上一篇博客中,我们学习了pygame事件与设备轮询.http://www.cnblogs.com/msxh ...

  7. Android中加载位图的方法

    Android中加载位图的关键的代码: AssetManager assets =context.getAssets(); //用一个AssetManager 对象来从应用程序包的已编译资源中为工程加 ...

  8. vs下取得资源文件中的版本信息

    在Windows Mobile和Wince(Windows Embedded CE)下开发的产品,有时候需要显示当前产品的版本信息.一般来说,版本信息是保存在资源文件里面的,例如下图: 为了保持一致, ...

  9. java中根据key获取resource下properties资源文件中对应的参数

    properties资源文件是放在resource目录下的: 新建工具类: package com.demo.utils; import java.io.InputStream; import jav ...

随机推荐

  1. CentOS 中使用yum出现的“UnicodeDecodeError: &#39;ascii&#39; codec”问题解决方法

    问题 新装了CentOS 6.5系统,打算使用yum安装程序是出现了例如以下错误: Loading mirror speeds from cached hostfile Traceback (most ...

  2. java基础 this keyword!

    为了程序的可读性,通常将一个类中的表示同一属性的变量进行统一的命名.可是这样做又会导致成员变量与局部变量名字冲突导致无法訪问成员变量.为了解决问题,java中引入了this这个keyword!所以th ...

  3. CentOS7 启动[root@localhost ~]# systemctl start docker Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for de

    1).在linux虚拟机上安装docker步骤:1.检查内核版本,必须是3.10及以上uname ‐r2.安装dockeryum install docker3.输入y确认安装4.启动docker[r ...

  4. codeforces 701 B. Cells Not Under Attack

    B. Cells Not Under Attack time limit per test 2 seconds memory limit per test 256 megabytes input st ...

  5. MVC:一个View显示多个Model(多个Model你可以使用ViewBag或ViewData , 或者:Model["myInfo"] as)

    MVC:一个View显示多个Model 多个Model你可以使用ViewBag或ViewData , 或者:Model["myInfo"] as. 比如: Tuple<str ...

  6. UVA Building designing

    题目总结来说求一段序列,必须正负交替,且绝对值递增 #include <iostream> #include <cstdio> #include <cstring> ...

  7. MyEclipse的代码自动提示功能

     一般默认情况下,Eclipse ,MyEclipse的代码提示功能是比Microsoft Visual Studio的差很多的,主要是Eclipse ,MyEclipse本身有很多选项是默认关闭的, ...

  8. js垃圾回收机制理解

    原理 找到不再被使用的变量,然后释放其占用的内存,但这个过程不是时时的,因为其开销比较大, 所以垃圾回收器会按照固定时间间隔周期性的执行 回收方式 a.标记清除 当变量进入环境时,将这个变量标记为“进 ...

  9. 51nod 更难的矩阵取数问题 + 滚动数组优化

    这里要求要走到终点再走回来,可以转化为两个人走. 那么我们可以先粗暴的设f[x1][y1][x2][y2]为第一个人走到(x1, y1), 第二个人走到(x2, y2)的最大价值. 那么这样空间会很大 ...

  10. OpenJDK源码研究笔记(十一):浅析Javac编译过程中的抽象语法树(IfElse,While,Switch等语句的抽象和封装)

    浅析OpenJDK源码编译器Javac的语法树包com.sun.source.tree. 抽象语法树,是编译原理中的经典问题,有点难,本文只是随便写写. 0.赋值语句 public interface ...