在使用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. VS2010:“error C2712: 无法在要求对象展开的函数中使用 __try”

    ZC:这个错误是在使用 "__try{...} __except(EXCEPTION_EXECUTE_HANDLER){}"时 遇到的 http://blog.csdn.net/c ...

  2. Spring Cloud 入门教程(四): 分布式环境下自动发现配置服务

    前一章, 我们的Hello world应用服务,通过配置服务器Config Server获取到了我们配置的hello信息“hello world”. 但自己的配置文件中必须配置config serve ...

  3. 类的调用1(被调用的MyFirstJava)

    package com.mec.MyFirstJavaLife.text; public class MyFirstJava { /**   * @param args   */ private in ...

  4. lua --- 逻辑运算符小结

    lua中的逻辑运算符,认为只有false.nil为假,其他的都为真(包括0.空串) a and b    -- 如果a为false,则返回a,否则返回b a or b   -- 如果a为true,则返 ...

  5. c# 读取txt方法

    string strLine; try { FileStream aFile = new FileStream("Log.txt", FileMode.Open); StreamR ...

  6. breakthroughs in statistics | 统计学历史

    <breakthroughs in statistics>- 这本书理解透了,统计方面应该可以封神了. 亚马逊上有卖,貌似还有好几卷. Breakthroughs in Statistic ...

  7. 利用WCF实现上传下载文件服务

    使用WCF上传文件           在WCF没出现之前,我一直使用用WebService来上传文件,我不知道别人为什么要这么做,因为我们的文件服务器和网站后台和网站前台都不在同一个机器,操作人员觉 ...

  8. Tempter of the Bone HDU - 1010

    The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it u ...

  9. python记录_day08

    今日内容:文件操作 一.文件基本操作 f = open("文件路径和文件名", mode=" r", encoding="utf-8" ) ...

  10. SqlSever查询某个表的列名称、说明、备注、注释,类型等

    这周整理了数据库文档,发现用导出脚本来整理表的信息注释查看不方便,因此我就想能不能SQL语句查询表的注释或者表的字段.我就我问朋友是不是可以,他给我点指导,然后自己也在网上百度,来实现自己的想法,我把 ...