在使用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. anusplina 4.36版本使用提示 说明

    1),必须要注意的是,你生成的dat文件中,第一列必须是气象站点编号:第二列必须是经度数值,而且是投影坐标下,以 米 为单位:第三列必须是纬度了:第四列必须是海拔了:之后就是你自己的数据,比如平均温度 ...

  2. echarts 拼图和折线图的封装 及常规处理

    1.html <div id="wrap"></div> 2.js ; (function ($) { $.fn.extend({ echartsPie: ...

  3. const修饰函数

    #include <iostream> using namespace std; class A { public: A(int age); void printAge() const; ...

  4. 牛客国庆集训派对Day3 A Knight

    Knight 思路: bfs打表找规律 如下图 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) ...

  5. C#获取路径中最后一个文件夹的名字

    using System; using System.IO; namespace ConsoleApplication1 { class Program { static void Main(stri ...

  6. (转)SPI时钟极性、时钟相位

    SPI协议是一个 4 线.全双工的串口协议.根据串口时钟SCLK的相位SCPH和极性SCPOL的不同,有 4 种组合. CPOL CPHA MODE0 0 0 MODE1 0 1 MODE2 1 0 ...

  7. ionic this.navCtrl.push()和this.navCtrl.pop()

    在ionic中,this.navCtrl.push()和this.navCtrl.pop()都是进行页面跳转,但是用法又有区别 例如有A  B  C三个页面,三个页面都是使用this.navCtrl. ...

  8. 关于Android 主题的那些事

    最近遇到了一个问题,主题的ActionBar的Title 颜色是黑色的 但是我的主界面由于用的是CoordinateLayot所以是白色的 整个黑色的就很难看 所以也想要把ActionBar 的Tit ...

  9. stark 组件 url 二级分发的实现

    模拟 admin 组件url设计思路 项目urls 文件中: from django.contrib import admin from django.urls import path from st ...

  10. wdcp环境安装filephp扩展

    网址 :https://blog.csdn.net/m_nanle_xiaobudiu/article/details/80838424