在使用Direct2D绘制图片的过程中,通过IWICImagingFactory工厂接口来得到绘制图片所需要的资源。本小节将介绍如何通过IWICImagingFactory工厂接口得到这些资源,并使用这些资源在应用窗口中绘制一张图片。在20.7.1小节所新建的Direct2DDemo项目基础上,继续介绍绘制图片的实现代码。

在绘制图片之前,首先需要在项目中添加一张图片。右键点击解决方案资源管理器窗口中的项目图标,在弹出的菜单栏中选中"添加",并在"添加"的子菜单栏中选择"现有项",在出现的"添加现有项"窗口中选择名为"Fruit.jpg"的图片文件,单击"添加"按钮将这个图片文件添加到项目中。

将图片添加到项目中以后,接下来打开D2DBasicAnimation.h头文件,并在D2DBasicAnimation类中添加如下的代码:

private:

    //声明成员变量 logoBitmap

    Microsoft::WRL::ComPtr<ID2D1Bitmap> logoBitmap;

    //声明成员变量 logoSize

    D2D_SIZE_F logoSize;

private:

    //获得位图

    void CreateBitmap();

在上面的代码中,使用private关键字声明两个私有的成员变量logoBitmap和logoSize,其中logoBitmap为ID2D1Bitmap类型的指针,logoSize为D2D1_SIZE_F结构体的变量,并使用private关键字声明一个私有的函数CreateBitmap,用于获得位图。

声明了CreateBitmap函数以后,接着打开D2DBasicAnimation.cpp源文件并添加CreateBitmap函数的实现代码,具体代码如下所示:

//得到位图

void D2DBasicAnimation::CreateBitmap()

{

    //声明IWICBitmapDecoder类型的指针

    ComPtr<IWICBitmapDecoder> wicBitmapDecoder;

    DX::ThrowIfFailed(

        wicFactory->CreateDecoderFromFilename(

            L"Fruit.jpg",

            nullptr,

            GENERIC_READ,

            WICDecodeMetadataCacheOnDemand,

            &wicBitmapDecoder

        )

    );

    ComPtr<IWICBitmapFrameDecode> wicBitmapFrame;

    DX::ThrowIfFailed(

        wicBitmapDecoder->GetFrame(0, &wicBitmapFrame)

    );

    ComPtr<IWICFormatConverter> wicFormatConverter;

    //得到IWICFormatConverter类型的对象

    DX::ThrowIfFailed(

    wicFactory->CreateFormatConverter(&wicFormatConverter)

    );

    //初始化wicFormatConverter指针所指向的对象

    DX::ThrowIfFailed(

        wicFormatConverter->Initialize(

            wicBitmapFrame.Get(),

            GUID_WICPixelFormat32bppPBGRA,

            WICBitmapDitherTypeNone,

            nullptr,

            0.0,

            WICBitmapPaletteTypeCustom

        )

    );

    //获取X轴和Y轴方向上的DPI

    double dpiX;

    double dpiY;

    DX::ThrowIfFailed(

        wicFormatConverter->GetResolution(&dpiX, &dpiY)

    );

    //得到ID2D1Bitmap类型的对象

    DX::ThrowIfFailed(

        d2dContext->CreateBitmapFromWicBitmap(

            wicFormatConverter.Get(),

            BitmapProperties(

            PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),static_cast<float>(dpiX),static_cast<float>(dpiY)),

            &logoBitmap

        )

    );

    //得到位图的大小

    logoSize = logoBitmap->GetSize();

}

在上面的代码中,首先声明一个IWICBitmapDecoder类型的指针wicBitmapDecoder,接着以要解码的图片的路径为第一个参数,调用wicFactory指针所指向的对象的CreateDecoderFromFilename函数得到一个IWICBitmapDecoder类型的对象,并使用wicBitmapDecoder指针指向这个对象,此对象表示一个图片解码器用于对图片进行解码。

接下来声明一个IWICBitmapFrameDecode类型的指针wicBitmapFrame,并调用wicBitmapDecoder指针所指向的对象的GetFrame函数得到一个IWICBitmapFrameDecode类型的对象,使用wicBitmapFrame指针指向这个对象。然后声明一个IWICFormatConverter类型的指针wicFormatConverter,并调用wicFactory指针所指向的对象的CreateFormatConverter函数得到一个IWICFormatConverter类型的对象,使用wicFormatConverter指针指向这个对象。接着调用wicFormatConverter指针所指向的对象的Initialize函数来设置图片解码后的格式,将图片的编码方式设置为GUID_WICPixelFormat32bppPBGRA,即图片每个像素使用32位存储,图片透明度设置为0.0,即图片不透明。声明两个double类型的变量dpiX和dpiY,接着调用wicFormatConverter指针所指向的对象的GetResolution函数获取两个浮点数,用于表示位图在X轴和Y轴方向上的DPI值,并分别赋值给dpiX变量和dpiY变量。

接下来调用d2dContext指针所指向的对象的CreateBitmapFromWicBitmap函数得到一个用于表示位图的ID2D1Bitmap类型的对象,使用logoBitmap指针指向这个对象。最后调用logoBitmap指针所指向的对象的GetSize函数得到位图的大小,并赋值给结构体变量logoSize。

添加了CreateBitmap函数的实现代码以后,接下来在D2DBasicAnimation.cpp源文件的CreateDeviceResources函数中分别调用DirectXBase类的CreateDeviceResources函数和上面定义的CreateBitmap函数,代码如下所示:

void D2DBasicAnimation::CreateDeviceResources()

{

    //调用DirectXBase类的CreateDeviceResources函数

    DirectXBase::CreateDeviceResources();

    //得到位图

    CreateBitmap();

}

下面在D2DBasicAnimation.cpp源文件的Render函数中实现图片的绘制,具体代码如下所示:

void D2DBasicAnimation::Render()

{

    //调用BeginDraw函数开始绘图

    d2dContext->BeginDraw();

    //设置应用窗口的背景颜色

    d2dContext->Clear(D2D1::ColorF(D2D1::ColorF::Gray));

    //绘制图片

    d2dContext->DrawBitmap(

        logoBitmap.Get(),

        D2D1::RectF(0.0f, 0.0f, logoSize.width, logoSize.height)

    );

    d2dContext->EndDraw();

}

在上面的代码中,首先调用d2dContext指针所指向的对象的BeginDraw函数开始绘制图片,接着通过d2dContext指针所指向的对象的Clear函数将应用窗口的背景颜色设置为灰色。然后使用d2dContext指针所指向的对象的DrawBitmap函数绘制图片,DrawBitmap函数有两个参数,其中第一个参数是图片的资源,这里将logoBitmap指针所指向的对象作为第一个参数。DrawBitmap函数的第二个参数用来设置绘制图片的大小,这里使用矩形区域作为第二个参数,通过D2D1::RectF函数得到一个矩形区域,并设置该矩形区域的左上角坐标为{0.0f,0.0f},矩形区域的右下角坐标为{ logoSize.width,logoSize.height },其中logoSize.width和logoSize.height分别表示位图的宽和高。最后调用d2dContext指针所指向的对象的EndDraw函数结束图片的绘制操作。

运行Direct2DDemo项目后,将在应用窗口中绘制如图20-18所示的图片。

图20-18 Direct2D绘制的图片

Win10系列:VC++绘制位图图片的更多相关文章

  1. 前端工程师技能之photoshop巧用系列第四篇——图片格式

    × 目录 [1]图片格式 [2]保存设置 前面的话 对于前端来说,图片格式是需要重要掌握的知识.本文是photoshop巧用系列第四篇——图片格式 图片格式 目前在前端的开发中常用的图片格式有jpg. ...

  2. android绘制圆形图片的两种方式

    看下效果先 下面有完整的示例代码 使用BitmapShader(着色器) 我们在绘制view 的时候 就是小学上美术课 用水彩笔在本子上画画 使用着色器绘制圆形图片最简单的理解方式 就是把bitmap ...

  3. WPF技术触屏上的应用系列(五): 图片列表异步加载、手指进行缩小、放大、拖动 、惯性滑入滑出等效果

    原文:WPF技术触屏上的应用系列(五): 图片列表异步加载.手指进行缩小.放大.拖动 .惯性滑入滑出等效果 去年某客户单位要做个大屏触屏应用,要对档案资源进行展示之用.客户端是Window7操作系统, ...

  4. 使用MFC CImage类绘制PNG图片时遇到的问题

    为了测试CImage绘制PNG图片的效果,我们用截图软件截得一张360的界面,然后使用PhotoShop等工具在图片的周边加上了透明的区域,然后保存成PNG图片文件.CImage首先从文件中加载,即 ...

  5. BMCP位图图片压缩算法

    什么是位图?位图也称像素图像或点阵图像,是由多个点组成的,这些点被称为像素.位图可以模仿照片的真实效果,具有表现力强.细腻.层次多和细节多等优点. 图片的压缩格式:在Windows系统中,我们常见的b ...

  6. windows程序设计 加载位图图片

    现在网上随便下个jpg图片,用windows自带的画图工具打开,点击画图工具左上角,文件->另存为->选择bmp,点击保存,保存好后,就得到一张位图了. 得到的位图,位图的内存比原图片jp ...

  7. Android Developers:绘制9-patch图片

    绘制9-patch图片工具让你使用可见即可得(WYSIWYG)编辑器轻松创建Nine Patch图像. 关于介绍Nine-path图片和它是如何工作的,请在2D Graphics的文档中查阅关于Nin ...

  8. WPF GDI+字符串绘制成图片(二)

    原文:WPF GDI+字符串绘制成图片(二) 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/BYH371256/article/details/83 ...

  9. WPF GDI+字符串绘制成图片(一)

    原文:WPF GDI+字符串绘制成图片(一) 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/BYH371256/article/details/83 ...

随机推荐

  1. [转][C++]佛祖保佑,永无bug。C++ BUG解决方案

    // // _oo0oo_ // o8888888o // 88" . "88 // (| -_- |) // 0\ = /0 // ___/`---'\___ // .' \\| ...

  2. git 先创建本地仓库,再关联远程

    之前都是先在GitHub或者bitbucket上创建repo,然后在本地直接git clone下来. 如果一定需要先在本地创建好文件夹,然后再关联远程仓库. 是这样: 1在远程创建仓库这步不变. 2 ...

  3. 在线html编辑器

    1.http://liveweave.com/ 2.有时间研究下这个. http://dabblet.com/gist/4034534 3.10个免费的在线编辑器. https://www.ev这个需 ...

  4. Unity中利用光线投射实现摄像机拉近追踪对象

    项目中要求实现摄像机跟踪人物移动,并且可以水平360°,上下接近180°的自由旋转.这些操作网上已近有很多版本的实现,在此不再赘述.我在此想说的是,当摄像机移动到场景边界,或者触碰到场景中的障碍物的时 ...

  5. Getting started with Processing 第十一章——数组

    Getting started with Processing 第十一章——数组 从变量到数组: 使用数组,无需为每一个变量创建一个新的名称/这让代码变得更短,更容易理解,更方便更新. 创建数组的三个 ...

  6. C语言流控制命令的总结

    C语言流控制命令的总结 基本概念: C语言中,自顶向下的的代码的流程叫做程序流. 能够改变程序流顺序的语句叫做流控制命令. 我为什么要写这篇文章 在学习C语言的过程中,经常会用到条件语句和循环语句这些 ...

  7. springboot---->java.lang.IllegalArgumentException

    springboot aop编程时,在方法上加入通知的注解,添加织入路径测试,发生报错: java.lang.IllegalArgumentException: Pointcut is not wel ...

  8. LeetCode--434--字符串中的单词数

    问题描述: 统计字符串中的单词个数,这里的单词指的是连续的不是空格的字符. 请注意,你可以假定字符串里不包括任何不可打印的字符. 示例: 输入: "Hello, my name is Joh ...

  9. 11月27日 招聘网第七部分,.gitignore的用法。

    回想Rails --Active Record Query Interface--Scopes的基本用法: 1.Passing in arguments.例子:scope  :name , -> ...

  10. Web3.js 0.20.x API 中文版翻译

    文档原始链接为:https://web3.learnblockchain.cn/0.2x.x/,欢迎大家前往查阅,本文只是节选开头部分的介绍及API列表索引,以下为翻译正文: 为了开发一个基于以太坊的 ...