精华内容
下载资源
问答
  • Direct2D图像 使用Direct2D的Delphi 10.2的图像组件 该组件的目的是使用Direct2D作为后端,以比标准TImage组件更好的抗锯齿显示图像。 Windows 7和更高版本是使用它所必需的。
  • Direct2D教程

    2015-10-14 11:43:31
    本文详细介绍了Direct2D编程的方方面面,尤其适合direct2d初学者使用;作者不仅文笔流畅,而且对于技术细节描述非常详尽,读者阅后不仅能够熟悉direct2d编程步骤,对于图形处理也会有一定的感知。
  • Windows操作系统 Vortice.Windows是Win32和UWP库的集合,具有对 , , , , , , , , 和绑定支持。 这个项目的诞生是因为最近不活跃,其目标是拥有.NET Standard 2.0 API和使用诸如Unsafe和SharpGen.Runtime之...
  • MFC direct2d 混编

    2019-12-08 16:12:06
    MFC direct2d 混编,演示创建一个绘制文本的static控件。传统的Static控件文本绘制容易闪烁,解决此类问题需要用双缓冲,而direct2d技术则默认是双缓冲,并且异常高效。
  • 渲染SVG的三个引擎(GDI +,Direct2D或Cairo)和四个组件来简化SVG图像的使用(调整大小,固定颜色,灰度...) 实际正式版2.2.5(VCL + FMX) 成分 描述 TSVGIconImageCollection是Delphi的SVG图像的集合,以提供...
  • Direct2D通过ID2D1RenderTarget接口支持基本图元(直线,矩形,圆角矩形,椭圆等)的绘制,然而,此接口并未提供对曲线绘制的直接支持。因此,想要使用Direct2D绘制一段通过指定点的曲线,比如Bezier曲线,必须借助...
  • Direct2D 1.1 可能听起来像一个次要版本更新,但实际上它有很大的变化,首先初始化工作就变得很复杂,它依赖从D3D来初始化。由此可以看出D2D1.1可以很好的和D3D一起工作,毕竟D3D也少不了2D绘图,特别是文字方面。...
  • Direct2D烟花程序

    2019-08-07 16:04:10
    使用Direct2D写的一个烟花小程序,可以手动设置参数 如炮弹速度、爆炸粒子数量、粒子颜色范围等
  • 梦幻海岸2D Direct2D를 이용한 基于等距平铺的动作角色扮演游戏项目 ============ 工作日记 2014 年 11 月 过去一个月 ============ 许可证
  • Direct2D 1.1 开发笔记 特效篇(一) 使用D2D特效》附带资源
  • WPF Direct2D 入门

    2018-04-18 21:21:25
    实际上现在很多小伙伴对于渲染性能就是听到 DirectX 才会去搜索这个博客。我在博客园看到很少的博客讲到这个。即使有也很少会说如何使用 WPF 的,这是我博客的例子,直接打开可以运行,详细请看我博客 lindexi.gitee...
  • Direct2D编程例子

    2016-06-29 10:44:06
    该例子是一个基于visual Stuido 2015的一个Direct2D的实际例子,该例子实现了Direct2D的图形绘制,文字显示,2D动画显示,图像显示,图形动画等内容,是学习Direct2D编程比较好的完整的程序,采用c/C++语言编写。...
  • .NET库,用于通过Direct2D进行硬件加速的高性能即时模式渲染。 通过使用图形上下文在Windows窗体上绘制任何内容,可以通过Direct2D控制或绘制内存。 图形界面的设计类似于普通的Windows Form图形界面,它易于学习...
  • Engine:使用D3D11D3D12,Direct2D,XAudio2,Qt的游戏引擎框架
  • win10系统加载动画 调用了Direct2D绘制,内附D2D模块 XP不可用! XP不可用! XP不可用 ! 因为Direct2D不支持XP系统
  • 该库基于.net4.0 已完成破解,使用官方2015版进行开发后,最后进行替换,方便在低版本的运行库上 进行兼容
  • 使用基于ActiveX的新硬件加速接口绘制矢量。
  • Direct2D,DirectWrite,Windows API,C ++,std :: shared_ptr等
  • Direct2D 官方例子

    2016-01-14 10:58:48
    非原创,官方资源,具体例子的中文说明可以在MSDN中找到.
  • MFC中GDI与Direct2D交互_D2D1_例子
  • Direct2D API参考

    2015-11-26 11:39:42
    完全来自于微软官网,作者只是收集整理了一下,方便大家使用
  • 目前,在博客园上,相对写得比较好的三个关于Direct2D的教程系列,分别是万一的Direct2D系列,万仓一黍的Direct2D系列和zdd的Direct2D系列。1、万一的 Direct2D 系列,用的是Delphi 20092、万仓一黍的 Direct2D教程 ...

    目前,在博客园上,相对写得比较好的三个关于Direct2D的教程系列,分别是万一的Direct2D系列,万仓一黍的Direct2D系列和zdd的Direct2D系列。

    1、万一的 Direct2D 系列,用的是Delphi 2009

    2、万仓一黍的 Direct2D教程 系列,用的是VS2010的Visual Basic语言

    3、zdd的 Direct2D 系列,用的是VS中的C++

    有兴趣的网友可以去看看。本系列也是介绍Direct2D的教程,是基于Visual C#的SlimDX库Direct2D的教程

    使用 Direct2D 绘制该矩形的代码和GDI+很相似:它创建绘制资源,说明要绘制的形状,绘制该形状,然后释放绘制资源。下面几节详细说明以上每个步骤。

    一.引用命名空间

    usingSlimDX;using SlimDX.Direct2D;

    二.所有 Direct2D 示例首先要完成一些任务,其中之一就是创建 Factory

    Factory factory;public voidInitDx2D()

    {

    factory= new Factory(FactoryType.SingleThreaded); //创建单线程工厂对象

    }

    Factory是使用 Direct2D 的起点;使用 Factory可创建 Direct2D 资源。

    创建工厂时,可指定它是多线程还是单线程的。(有关多线程工厂的详细信息,请参见 ID2D1Factory 参考页面上的备注。)此示例创建一个单线程工厂。

    一般而言,应用程序应创建一次工厂,然后在应用程序的生命周期中保留它。

    三.创建 WindowRenderTarget

    创建工厂之后,使用它来创建呈现器目标。

    RenderTargetProperties RTproperties = newRenderTargetProperties();

    RTproperties.Type= RenderTargetType.Hardware; //指定呈现器类型

    WindowRenderTargetProperties WRTproperties= new WindowRenderTargetProperties(); //呈现器目标的初始大小(以像素为单位)及其显示选项

    WRTproperties.Handle =intPtr;

    WRTproperties.PixelSize= this.ClientSize; //显示大小

    WRTproperties.PresentOptions = PresentOptions.None; //使用默认显示选项

    renderTarget= new WindowRenderTarget(factory, RTproperties, WRTproperties);

    呈现器目标是一种设备,可执行绘制操作和创建与设备相关的绘制资源,如画笔。不同类型的呈现器目标呈现到不同设备。前面的示例使用 WindowRenderTarget,它呈现到一部分屏幕上。

    此段加入到上面的 public voidInitDx2D(IntPtr intPtr) {  }

    四.创建渲染函数

    public voidRender()

    {if (renderTarget == null)

    {return;

    }

    renderTarget.BeginDraw();//开始绘制

    Ellipse e = new Ellipse() { Center=new PointF(50,50), RadiusX=30, RadiusY=40}; //创建椭圆对象

    SolidColorBrush brush = new SolidColorBrush(renderTarget, new Color4(Color.Red)); //创建画刷

    renderTarget.DrawEllipse(brush, e); //绘制椭圆

    renderTarget.EndDraw();

    }

    五.总结一下,这个类的代码应该是下面这样子

    usingSlimDX;usingSlimDX.Direct2D;usingSystem.Windows.Forms;usingSystem.Drawing;namespaceDemo1Test

    {classDemo1

    {

    Factory factory;

    WindowRenderTarget renderTarget;public voidInitDx2D(Control control)

    {

    factory= new Factory(FactoryType.SingleThreaded); //创建工厂对象

    RenderTargetProperties RTproperties= newRenderTargetProperties();

    RTproperties.Type= RenderTargetType.Hardware; //指定呈现器类型

    WindowRenderTargetProperties WRTproperties= new WindowRenderTargetProperties(); //呈现器目标的初始大小(以像素为单位)及其显示选项

    WRTproperties.Handle =control.Handle;

    WRTproperties.PixelSize= control.ClientSize; //显示大小

    WRTproperties.PresentOptions = PresentOptions.None; //使用默认显示选项

    renderTarget= newWindowRenderTarget(factory, RTproperties, WRTproperties);

    }public voidRender()

    {if (renderTarget == null)

    {return;

    }

    renderTarget.BeginDraw();//开始绘制

    Ellipse e = new Ellipse() { Center = new PointF(50, 50), RadiusX = 30, RadiusY = 40 }; //创建椭圆对象

    SolidColorBrush brush = new SolidColorBrush(renderTarget, new Color4(Color.Red)); //创建画刷

    renderTarget.DrawEllipse(brush, e); //绘制椭圆

    renderTarget.EndDraw();

    }

    }

    }

    六.测试调用,新建一个Windows窗体应用程序 Demo1Test, 分别在窗体的 Form1_Load 事件下初始化 Demo1 对象, 在窗体的 Form1_Paint 事件下渲染对象, 看起来像下面这样子

    usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Windows.Forms;namespaceDemo1Test

    {public partial classForm1 : Form

    {publicForm1()

    {

    InitializeComponent();

    }

    Demo1 test;private void Form1_Load(objectsender, EventArgs e)

    {

    test= newDemo1();

    test.InitDx2D(this);

    }private void Form1_Paint(objectsender, PaintEventArgs e)

    {

    test.Render();

    }

    }

    }

    最后的结果

    展开全文
  • Windows 2D 绘图 (GDI, GDI+, Direct2D)

    千次阅读 2019-02-12 18:05:28
    Windows 2D 绘图GDIGDI 函数GDI+GDI 和 GDI+ 的区别GDI+ 新特性Direct2D视觉效果demo GDI GDI 是 Graphics Device Interface 的缩写,含义是图形设备接口,它的主要任务是负责系统与绘图程序之间的信息交换,处理...

    GDI

    GDI 是 Graphics Device Interface 的缩写,含义是图形设备接口,它的主要任务是负责系统与绘图程序之间的信息交换,处理所有 Windows 程序的图形输出。

    在 Windows 操作系统下,绝大多数具备图形界面的应用程序都离不开 GDI,我们利用 GDI 所提供的众多 API 就可以方便的在屏幕、打印机及其它输出设备上输出图形、文本等操作。

    GDI 具有如下特点:

    • 不允许程序直接访问物理显示硬件,通过称为“设备环境”的抽象接口间接访问显示硬件
    • 程序需要与显示硬件(显示器、打印机等) 进行通讯时,必须首先获得与特定窗口相关联的设备环境
    • 用户无需关心具体的物理设备类型
    • Windows 参考设备环境的数据结构完成数据的输出

    GDI 函数

    GDI 函数大致可分类为:

    • 设备上下文函数(如 GetDC、CreateDC、DeleteDC)
    • 画线函数(如 LineTo、Polyline、Arc)
    • 填充画图函数(如 Ellipse、FillRect、Pie)
    • 画图属性函数(如 SetBkColor、SetBkMode、SetTextColor)
    • 文本、字体函数(如 TextOut、GetFontData)
    • 位图函数(如 SetPixel、BitBlt、StretchBlt)
    • 坐标函数(如 DPtoLP、LPtoDP、ScreenToClient、ClientToScreen)
    • 映射函数(如 SetMapMode、SetWindowExtEx、SetViewportExtEx)
    • 元文件函数(如 PlayMetaFile、SetWinMetaFileBits)
    • 区域函数(如 FillRgn、FrameRgn、InvertRgn)
    • 路径函数(如 BeginPath、EndPath、StrokeAndFillPath)
    • 裁剪函数(如 SelectClipRgn、SelectClipPath)

    GDI+

    GDI+ 是 GDI 的后续版本,最早于 2000 年随 Windows 2000 一起推出,后来又被包装进 .NET 框架的托管类库中,成为 .NET 中窗体绘图的主要工具。

    GDI+ 主要提供了以下三类服务:

    • 二维矢量图形:GDI+ 提供了存储图形基元自身信息的类(或结构体)、存储图形基元绘制方式信息的类以及实际进行绘制的类;
    • 图像处理:大多数图片都难以划定为直线和曲线的集合,无法使用二维矢量图形方式进行处理。因此,GDI+ 为我们提供了 Bitmap、Image 等类。它们可用于显示、操作和保存 BMP、JPG、GIF 等图像。
    • 文字显示:GDI+ 支持使用各种字体、字号和样式来显示文本。

    GDI 接口是基于函数的,而 GDI+ 是基于 C++ OO 的编程接口,因此使用起来比 GDI 要方便。因为 GDI+ 实际上是 GDI 的封装和扩展,所以执行效率一般要低于 GDI。
    GDI+

    GDI 和 GDI+ 的区别

    GDI 的核心是设备上下文,GDI 函数都依赖于设备上下文句柄,其编程方式是基于句柄的;GDI+ 无需时刻依赖于句柄或设备上下文,用户只需创建一个 Graphics 对象,就可以用面向对象的方式调用其成员函数进行图形操作,编程方式是基于对象的。

    GDI 在使用设备上下文绘制线条之前,必须先调用 SelectObject 以使钢笔对象和设备上下文关联。其后,在设备上下文中绘制的所有线条均使用该钢笔,直到选择另一支不同的钢笔为止。GDI 中有当前位置的概念,所以在使用 GDI 绘制线条前应该先使用MoveTo 移动当前位置,再使用 LineTo 画线。

      CPen pen(PS_SOLID, 1, RGB(255, 0, 0));
      dc.SelectObject(pen.GetSafeHandle());
      dc.MoveTo(0, 0);
      dc.LineTo(100, 100);
    

    在 GDI+ 中,只需将 Pen 对象直接作为参数传递给 Graphics 类的 DrawLine 等方法即可,而不必使 Pen 对象与 Graphics 对象关联。且 GDI+ 中则没有当前位置的概念,画线函数中可以直接指定起点和终点。

      Pen myPen(Color::Red);
      graphics.DrawLine(&myPen, 0, 0, rect.right, 0);
    

    GDI+ 新特性

    • 改进了颜色管理
      GDI+ 不仅提供了更多可供选择使用的颜色,使其支持 Alpha 通道合成运算,而且还保持了与其他颜色的兼容性。
    • 绘图支持反锯齿
      通过设置 GDI+ 对象的相关属性,GDI+ 可以与相关的显示驱动程序搭配完成图形绘制时的反锯齿功能,使得绘制的图形更加平滑、美观,而整个过程是由 GDI+ 对象自动计算完成的。
    • 提供渐变画刷
      GDI+ 拓展了 GDI 的功能,提供线性渐变和路径渐变画刷来填充图形、路径和区域,甚至也可用来绘制直线、曲线等。
    • 独立的路径对象
      GDI+ 使用 Graphics 对象来进行绘图操作,并将路径操作从 Graphics 对象分离出来,提供一个 Graphics 类供用户使用,用户不必担心对象会受到 Graphics 对象操作的影响,从而可以使用同一个操作对象进行多次的路径绘制操作。
    • 样条曲线
      GDI+ 封装了绘制基数样条曲线和贝塞尔样条曲线的方法。
    • 变形和矩阵运算
      GDI+ 提供了功能强大的 Matrix 类来实现矩阵的旋转,错切、平移、比例等变换操作,以便产生复杂的新图形。
    • 多图片格式的支持
      GDI+ 改进了图形处理能力,通过 GDI+,用户能够访问多种格式的图片文件,转换文件格式等,还能进行图像重新着色、色彩修正、消除走样等图像处理。

    Direct2D

    Direct2D 是一个基于 Direct3D 的 2D 图形 API,可以利用硬件加速特性来提供高性能、高质量的 2D 渲染。而且十分方便的是,Direct2D 与 GDI,GDI+ 和 D3D 都是可以交互的。一项技术总是有其受众面,看看微软怎么说的:

    • 大型企业级本机应用程序开发人员。
    • 创建供下游开发人员使用的控件工具包和库的开发人员。
    • 需要对二维图形进行服务器端呈现的开发人员。
    • 使用 Direct3D 图形,并且需要在菜单、用户界面 (UI) 元素和抬头显示器 (HUD) 中使用高性能的简单二维和文本呈现的开发人员。
      direct2D
      在 Direct2D 架构的右下方,有一个软件光栅化(software rasterizer),假如显卡不支持硬件加速,那么 Direct2D 可以使用软件方式渲染,即便是这样,其效果还是要优于 GDI。

    视觉效果

    使用 Direct2D 渲染出来的效果要比 GDI 要好的多。因为 Direct2D 使用基于图元的反锯齿效果(这样会使线条更加的平滑),而且在渲染二维图元的时候,完全支持透明和 Alpha 混合。以下是对比的照片:
    direct2d vs gdi
    显然,右边的 Direct2D 的线条效果要好于左边的 GDI。

    demo

    • GDI
      正弦曲线
    • GDI+
      渐变色,Alpha混合
    • D2D
      螺旋路径动画
      2d draw demo

    GDI 绘图代码:

    void CChildView::_drawWithGDI( CPaintDC& dc )
    {
        CRect rect;
        GetClientRect(&rect);
    
        // 绘制 title
        dc.TextOut(10, 10, _T("GDI"), 3);
    
        //逻辑坐标与设备坐标变换
        dc.SetMapMode(MM_ANISOTROPIC);
        dc.SetWindowOrg(0, 0);
        dc.SetWindowExt(rect.right, rect.bottom);
        dc.SetViewportOrg(0, rect.bottom / 2);
        dc.SetViewportExt(rect.right, - rect.bottom);
    
        //创建绘制 x 轴的 pen 并将其选入设备上下文
        CPen penx(PS_SOLID, 1, RGB(0, 0, 255));
        HGDIOBJ oldObject = dc.SelectObject(penx.GetSafeHandle());
        //绘制 x 轴
        dc.MoveTo(0, 0);
        dc.LineTo(rect.right, 0);
    
        //创建绘制正旋曲线的 pen 并将其选入设备上下文
        CPen pen(PS_SOLID, 1, RGB(255, 0, 0));
        dc.SelectObject(pen.GetSafeHandle());
    
        //绘制正弦曲线
        dc.MoveTo(0, 0);
        for (int i = 0; i < rect.right; i++)
            dc.LineTo(i, (int)(100 * sin(2 *(i / (rect.right / 5.0)) * M_PI)));
    
        //恢复原先的 pen
        dc.SelectObject(oldObject);
    
        // 恢复逻辑坐标与设备坐标变换
        dc.SetViewportOrg(0, 0);
        dc.SetViewportExt(rect.right, rect.bottom);
    }
    

    GDI+ 绘图代码:

    void CChildView::_drawWithGDIPlus( CPaintDC& dc )
    {
        using namespace Gdiplus;
        CRect rect;
        GetClientRect(&rect);
    
        Graphics graphics(dc);
    
        //创建渐变画刷
        LinearGradientBrush lgb(Point(0, 0), Point(rect.right, rect.bottom), Color::Blue, Color::Purple);
        graphics.FillRectangle(&lgb, 0, 0, rect.right, rect.bottom);
    
        //创建ColorMatrix
        ColorMatrix ClrMatrix =
        {
            1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
            0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
            0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
            0.0f, 0.0f, 0.0f, 0.5f, 0.0f,
            0.0f, 0.0f, 0.0f, 0.0f, 1.0f
        };
    
        //将 ColorMatrix 赋给 ImageAttributes
        ImageAttributes ImgAttr;
        ImgAttr.SetColorMatrix(&ClrMatrix, ColorMatrixFlagsDefault,ColorAdjustTypeBitmap);
    
        FontFamily fontFamily1(_T("Calibri"));
        Font font1(&fontFamily1, 12, FontStyleRegular, UnitPoint);
    
        //Alpha 混合
        graphics.DrawString(_T("LENA"), 4, &font1, PointF(140.0f, 140.0f), &SolidBrush(Color::White));
        TCHAR szImgPath[MAX_PATH] = {0};
        //确保程序所在目录下存在 lena.png (res 文件夹下有)
        PathHelper::makeFullPathWithModuleDir(szImgPath, MAX_PATH, _T("lena.png"));
        Image img(szImgPath);
        graphics.DrawImage(&img, RectF(60, 140, 200, 200), 0, 0, 
            (REAL)img.GetWidth(), (REAL)img.GetHeight(), UnitPixel, &ImgAttr);
    
        // 绘制 title
        graphics.DrawString(_T("GDI+"), 4, &font1, PointF(10.0f, 10.0f), &SolidBrush(Color::White));
    }
    

    Direct2D 绘制代码(部分):

    HRESULT D2DImpl::render(HWND hwnd)
    {
        using namespace D2D1;
        HRESULT hr;
    
        hr = createDeviceResources(hwnd);
        RETURN_IF_FAILED(hr);
    
        int wndState = m_pRenderTarget->CheckWindowState();
        RETURN_IF_TRUE(wndState & D2D1_WINDOW_STATE_OCCLUDED, E_FAIL);
    
        D2D1_SIZE_F rtSize = m_pRenderTarget->GetSize();
    
        // Prepare to draw.
        m_pRenderTarget->BeginDraw();
    
        // Reset to identity transform
        m_pRenderTarget->SetTransform(Matrix3x2F::Identity());
    
        m_pRenderTarget->Clear(ColorF(ColorF::Black));
    
        TCHAR szTitle[] = _T("Direct2D");
        m_pRenderTarget->DrawText(
            szTitle,
            _tcslen(szTitle),
            m_pTextFormat,
            D2D1::RectF(10, 10, rtSize.width, rtSize.height),
            m_pTextBrush);
    
        //center the path
        float minWidthHeightScale = min(rtSize.width, rtSize.height) / 512;
        Matrix3x2F scale = Matrix3x2F::Scale(minWidthHeightScale, minWidthHeightScale);
        Matrix3x2F translation = Matrix3x2F::Translation(rtSize.width / 2, rtSize.height / 2);
        m_pRenderTarget->SetTransform(scale * translation);
    
        //draw the path in red
        m_pRenderTarget->DrawGeometry(m_pPathGeometry, m_pRedBrush);
    
        static float float_time = 0.0f;
        float length = m_animation.GetValue(float_time);
    
        D2D1_POINT_2F point;
        D2D1_POINT_2F tangent;
        // Ask the geometry to give us the point that corresponds with the length at the current time.
        hr = m_pPathGeometry->ComputePointAtLength(length, NULL, &point, &tangent);
    
        // Reorient the triangle so that it follows the direction of the path.
        D2D1_MATRIX_3X2_F triangleMatrix = Matrix3x2F(
            tangent.x, tangent.y,
            -tangent.y, tangent.x,
            point.x, point.y );
    
        m_pRenderTarget->SetTransform(triangleMatrix * scale * translation);
    
        // Draw the yellow triangle.
        m_pRenderTarget->FillGeometry(m_pObjectGeometry, m_pYellowBrush);
    
        // Commit the drawing operations.
        hr = m_pRenderTarget->EndDraw();
    
        if (hr == D2DERR_RECREATE_TARGET) {
            hr = S_OK;
            discardDeviceResources();
        }
    
        // When we reach the end of the animation, loop back to the beginning.
        if (float_time >= m_animation.GetDuration())
            float_time = 0.0f;
        else
            float_time += (float)(m_dwmTiming.rateCompose.uiDenominator) / (m_dwmTiming.rateCompose.uiNumerator);
    
        InvalidateRect(hwnd, NULL, FALSE);
    
        return hr;
    }
    

    Blueware
    EOF

    展开全文
  • 使用Direct2D高效(比GDI,GDI+快几倍)绘制多种风格的线条,作者使用VS2012编译,压缩包内仅包含一个cpp文件,所以方便转换到其他VisualStudio版本.zip
  • WPF 使用 Direct2D1 画图 绘制基本图形

    千次阅读 2018-04-19 16:43:07
    本文来告诉大家如何在 Direct2D1 绘制基本图形,包括线段、矩形、椭圆

    本文来告诉大家如何在 Direct2D1 绘制基本图形,包括线段、矩形、椭圆

    本文是一个系列

    本文的组织参考Direct2D,对大神表示感谢。

    在开始前先告诉大家为何需要使用 Direct2D ,虽然 WPF 也是基于 DX 进行渲染,但是 WPF 做了很多兼容处理,所以没有比直接使用 Direct2D 的性能高。经过测试,在使用下面的所有代码,占用 CPU 几乎都是 0% ,因为没有布局、透明和事件处理,所以速度是很快。

    在 Direct2D 使用的 点是 Point2F ,传入的是两个 float ,和 Point 差不多。

    Point2F 也是一个结构体,所以和 Point 类型差不多

    线段

    线段需要使用 DrawLine ,方法的签名

        public void DrawLine(Point2F firstPoint 起始点 , Point2F secondPoint 终点, Brush brush 笔刷, float strokeWidth 线段宽度)
    
     public unsafe void DrawLine(Point2F firstPoint, Point2F secondPoint, Brush brush, float strokeWidth, StrokeStyle strokeStyle 线段样式)
    

    所以使用下面的方法就可以在 (10,10) (100,10) 画出一条宽度为 2 的红线

                _renderTarget.DrawLine(new D2D.Point2F(10, 10), new D2D.Point2F(100, 10),
                    _renderTarget.CreateSolidColorBrush(new D2D.ColorF(1, 0, 0, 1)), 2);
    

    在这里插入图片描述

    上面的代码运行在WPF 使用 Direct2D1 画图入门文章的 OnRendering 方法,为了让大家也可以试试下面的代码,建议大家先去看这篇博客。

    关于笔刷会在后面说

    StrokeStyle

    可以看到上面线段的最后一个参数是 StrokeStyle 那么这个参数是如何创建?在 Direct2D 有很多类都不能直接直接创建需要使用 D2DFactory 或 RenderTarget 才能创建。StrokeStyle 就需要使用 D2DFactory 进行创建。

    创建 StrokeStyle 需要参数 StrokeStyleProperties,这个类的构造有两个重载,一个是不需要参数,另一个是需要很多参数。代码请看下面。

    public StrokeStyleProperties(CapStyle startCap, CapStyle endCap, CapStyle dashCap, LineJoin lineJoin, float miterLimit, DashStyle dashStyle, float dashOffset)
    

    从代码的命名大概大家也可以知道 StrokeStyleProperties 参数的意思,下面先创建一个没有构造函数的来创建 StrokeStyle ,请看下面代码

                var strokeStyleProperties = new D2D.StrokeStyleProperties();
    
                var strokeStyle = d2DFactory.CreateStrokeStyle(strokeStyleProperties);
    
                _renderTarget.BeginDraw();
    
                _renderTarget.DrawLine(new D2D.Point2F(10,10),new D2D.Point2F(100,10), _renderTarget.CreateSolidColorBrush(new D2D.ColorF(1, 0, 0, 1)),2, strokeStyle);
    
                _renderTarget.EndDraw();
    

    需要注意,创建 strokeStyle 的工厂需要和创建 RenderTarget 一样,如果使用不一样的工厂就会出现下面异常。

    Microsoft.WindowsAPICodePack.DirectX.Direct2D1.Direct2DException:EndDraw has failed with error: 一起使用的对象必须创建自相同的工厂实例。 (异常来自 HRESULT:0x88990012) Tags=(0,0).

    所以需要修改WPF 使用 Direct2D1 画图入门文章的代码,把 D2DFactory 写为字段

       public MainWindow()
            {
                InitializeComponent();
    
                CompositionTarget.Rendering += OnRendering;
    
                Loaded += (s, e) =>
                {
                    var d2DFactory = D2D.D2DFactory.CreateFactory(D2D.D2DFactoryType.Multithreaded);
    
                    var windowHandle = new WindowInteropHelper(this).Handle;
                    var renderTarget = d2DFactory.CreateHwndRenderTarget(new D2D.RenderTargetProperties(),
                        new D2D.HwndRenderTargetProperties(windowHandle,
                            new D2D.SizeU((uint) ActualWidth, (uint) ActualHeight),
                            D2D.PresentOptions.RetainContents));
    
                    _redBrush = renderTarget.CreateSolidColorBrush(new D2D.ColorF(1, 0, 0, 1));
    
                    _greenBrush = renderTarget.CreateSolidColorBrush(new D2D.ColorF(0, 1, 0, 1));
    
                    _blueBrush = renderTarget.CreateSolidColorBrush(new D2D.ColorF(0, 0, 1, 1));
    
                    _renderTarget = renderTarget;
    
                    _d2DFactory = d2DFactory;
                };
            }
    

    StrokeStyleProperties

    关于 StrokeStyleProperties 需要说一下,就是各个参数。

    从名字可以看到 StartCap 和 EndCap 就是线段的两端的图形,可以选的参数

    • Flat
    • Square
    • Round
    • Triangle

    具体表示是什么,我会使用下面的例子

    Flat

    平的

                var strokeStyleProperties = new D2D.StrokeStyleProperties();
    
                strokeStyleProperties.StartCap = D2D.CapStyle.Flat;
                strokeStyleProperties.EndCap = D2D.CapStyle.Flat;
    
                var strokeStyle = _d2DFactory.CreateStrokeStyle(strokeStyleProperties);
    
                _renderTarget.BeginDraw();
    
                _renderTarget.DrawLine(new D2D.Point2F(10,10),new D2D.Point2F(100,10), _renderTarget.CreateSolidColorBrush(new D2D.ColorF(1, 0, 0, 1)),2, strokeStyle);
    
                _renderTarget.EndDraw();
    

    在这里插入图片描述

    Round

    圆的

           float h = 10;
    
                strokeStyleProperties.StartCap = D2D.CapStyle.Round;
                strokeStyleProperties.EndCap = D2D.CapStyle.Round;
                strokeStyle = _d2DFactory.CreateStrokeStyle(strokeStyleProperties);
    
                h += 20;
    
                _renderTarget.BeginDraw();
    
                _renderTarget.DrawLine(new D2D.Point2F(10, h), new D2D.Point2F(100, h), _renderTarget.CreateSolidColorBrush(new D2D.ColorF(1, 0, 0, 1)), 5, strokeStyle);
    
                _renderTarget.EndDraw();
    

    Square

    方形

      strokeStyleProperties.StartCap = D2D.CapStyle.Square;
                strokeStyleProperties.EndCap = D2D.CapStyle.Square;
                strokeStyle = _d2DFactory.CreateStrokeStyle(strokeStyleProperties);
    
                h += 20;
    
                _renderTarget.BeginDraw();
    
                _renderTarget.DrawLine(new D2D.Point2F(10, h), new D2D.Point2F(100, h), _renderTarget.CreateSolidColorBrush(new D2D.ColorF(1, 0, 0, 1)), 5, strokeStyle);
    
                _renderTarget.EndDraw();
    

    Triangle

    三角形

    
                strokeStyleProperties.StartCap = D2D.CapStyle.Triangle;
                strokeStyleProperties.EndCap = D2D.CapStyle.Triangle;
                strokeStyle = _d2DFactory.CreateStrokeStyle(strokeStyleProperties);
    
                h += 20;
    
                _renderTarget.BeginDraw();
    
                _renderTarget.DrawLine(new D2D.Point2F(10, h), new D2D.Point2F(100, h), _renderTarget.CreateSolidColorBrush(new D2D.ColorF(1, 0, 0, 1)), 5, strokeStyle);
    
                _renderTarget.EndDraw();
    

    在这里插入图片描述

    DashStyle

    如果需要画虚线就可以使用 DashStyle ,虚线显示就是使用 CapStyle

    
                strokeStyleProperties.DashStyle = D2D.DashStyle.DashDot;
                strokeStyleProperties.DashCap = D2D.CapStyle.Square;
                strokeStyleProperties.DashOffset = 2;
    
                h += 20;
    
                strokeStyle = _d2DFactory.CreateStrokeStyle(strokeStyleProperties);
    
                _renderTarget.BeginDraw();
    
                _renderTarget.DrawLine(new D2D.Point2F(10, h), new D2D.Point2F(100, h),
                    _renderTarget.CreateSolidColorBrush(new D2D.ColorF(1, 0, 0, 1)), 5, strokeStyle);
    
                _renderTarget.EndDraw();
    

    大家自己试一试就知道

    里面还有属性 LineJoin 这个不是线段可以做的,是折线才可以使用,表示两个线段如何链接

    矩形

    画矩形使用 DrawRectangle ,参数需要传入 RectF 需要传入上下左右的浮点数。

                _renderTarget.DrawRectangle(new D2D.RectF(10, 10, 100, 100), brush, 10);
    
    

    矩形有两个重载

        public void DrawRectangle(RectF rect, Brush brush, float strokeWidth)
    
    
        public unsafe void DrawRectangle(RectF rect, Brush brush, float strokeWidth, StrokeStyle strokeStyle)
    

    矩形的 StrokeStyle 和线段一样。

    在这里插入图片描述

    椭圆

    实际上画圆和椭圆是一样的,画圆的函数有两个重载

        public void DrawEllipse(Ellipse ellipse, Brush brush, float strokeWidth)
    
    
     public unsafe void DrawEllipse(Ellipse ellipse, Brush brush, float strokeWidth, StrokeStyle strokeStyle)
    

    需要先创建 Ellipse 和笔刷。

    创建 Ellipse 需要给圆心和两个轴,下面创建一个圆心在 (100,100) ,两个轴都是50的椭圆。实际上就是半径是50的圆形。

                var ellipse = new D2D.Ellipse(new D2D.Point2F(100, 100), 50, 50);
    
    

    在这里插入图片描述

    这就是绘制基本的图形。

    那么如何填充图形?实际上所有 Draw 都有对应的 Fill 函数,除了线段。所以填充就是调用对应的 Fill 函数。

    尝试运行程序,看看这时的 CPU ,实际上是几乎不会动,因为所有的计算都在 GPU 计算。不过程序里的代码包括创建图形,实际上是在 CPU 创建,但是因为速度很快,几乎不需要计算,所以需要的时间很短。

    文字

    最后就是告诉大家如何绘制文字。

    绘制文字需要使用 DirectWrite ,需要先创建 DWriteFactory 然后才可以绘制文本。

    绘制文本有多个方式,因为需要的很多参数都不能直接创建需要使用 DWriteFactory 创建,所以这里需要先使用下面代码

                var dWriteFactory = DWriteFactory.CreateFactory();
    
    

    创建文字有多个方法

    public void DrawText(string text, TextFormat textFormat, RectF layoutRect, Brush defaultForegroundBrush)
    
    public void DrawText(string text, TextFormat textFormat, RectF layoutRect, Brush defaultForegroundBrush, MeasuringMode measuringMode)
    
    public void DrawText(string text, TextFormat textFormat, RectF layoutRect, Brush defaultForegroundBrush, DrawTextOptions options)
    
    public unsafe void DrawText(string text, TextFormat textFormat, RectF layoutRect, Brush defaultForegroundBrush, DrawTextOptions options, MeasuringMode measuringMode)
    
    
     public unsafe void DrawTextLayout(Point2F origin, TextLayout textLayout, Brush defaultForegroundBrush)
    
     public unsafe void DrawTextLayout(Point2F origin, TextLayout textLayout, Brush defaultForegroundBrush, DrawTextOptions options)
    

    因为有很多个参数,需要大家自己去试试

    下面来写出简单文字

    在这里插入图片描述

    需要先创建 textFormat 需要告诉使用哪个字形,和字体大小

                var textFormat = dWriteFactory.CreateTextFormat("宋体", 20);
    
    

    下面就是画出文字,文字换行可以使用\n,复杂的换行请使用文字重载方法,这里我就不说了

                _renderTarget.BeginDraw();
    
                _renderTarget.DrawText("lindexi 本文所有博客放在 lindexi.oschina.io \n欢迎大家来访问\n\n这是系列博客,告诉大家如何在 WPF 使用Direct2D1", textFormat, new D2D.RectF(10, 10, 1000, 1000), brush);
    
                _renderTarget.EndDraw();
    

    需要说的是 Windows API Code Pack 1.1 已经很久没更新,而且有错误,所以建议使用 SharpDX

    参见:Using Direct2D with WPF - CodeProject

    https://jeremiahmorrill.wordpress.com/2011/02/14/a-critical-deep-dive-into-the-wpf-rendering-system/

    知识共享许可协议
    本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

    展开全文
  • 关于:这是一个使用DirectX11和Direct2D来创建2D / 3D游戏引擎的游戏引擎,它将用作学习工具,使我能够扩展自己从大学获得的知识并在毕业后的自己的时间里学习。它将使用一个存档的非固定存储库(DirectX11Engine-旧...
  • Direct2D教程V——位图(Bitmap)和位图笔刷(BitmapBrush) 原文:Direct2D教程V——位图(Bitmap)和位图笔刷(BitmapBrush)目前博客园中成系列的Direct2D的教程有 1、万一的 Direct2D 系列,用的...
    原文: Direct2D教程V——位图(Bitmap)和位图笔刷(BitmapBrush)

    目前博客园中成系列的Direct2D的教程有

    1、万一的 Direct2D 系列,用的是Delphi 2009

    2、zdd的 Direct2D 系列,用的是VS中的C++

    3、本文所在的 Direct2D教程 系列,用的是VS2010的Visual Basic语言(可以很方便的转为C#),基于Windows API Code Pack 1.1。

     

    还有官方的说明文档 Direct2D ,用的是C++。

     

    本系列的前几篇文章:

    Direct2D教程I——简介及首个例子

    Direct2D教程II——绘制基本图形和线型(StrokeStyle)的设置详解

    Direct2D教程III——几何(Geometry)对象

    Direct2D教程IV——笔刷(Brush)对象

     

    Direct2D中的绘图函数

    在Direct2D中,RenderTarget对象的绘图函数是DrawBitmap和DrawBitmapAtOrigin。这两个函数的原型定义如下:

     
    Public  Sub DrawBitmap(bitmap As Direct2D1. D2DBitmap)
    Public  Sub DrawBitmap(bitmap As Direct2D1. D2DBitmap, opacity As  Single, interpolationMode As Direct2D1. BitmapInterpolationMode)
    Public  Sub DrawBitmap(bitmap As Direct2D1. D2DBitmap, opacity As  Single, interpolationMode As Direct2D1. BitmapInterpolationMode, destinationRectangle As Direct2D1. RectF)
    Public  Sub DrawBitmap(bitmap As Direct2D1. D2DBitmap, opacity As  Single, interpolationMode As Direct2D1. BitmapInterpolationMode, destinationRectangle As Direct2D1. RectF, sourceRectangle As Direct2D1. RectF)
    Public  Enum  BitmapInterpolationMode
        Linear = 1
        NearestNeighbor = 0
    End  Enum

    Public  Sub DrawBitmapAtOrigin(bitmap As Direct2D1. D2DBitmap, opacity As  Single, interpolationMode As Direct2D1. BitmapInterpolationMode, sourceRectangle As Direct2D1. RectF)

     

    从函数的原型定义可以看出,DrawBitmap函数有4个重载函数,我们以最后一个函数说明各个参数的意义。

    参数bitmap:要绘制的位图对象。参数类型是D2DBitmap类。

    参数opacity:不透明度。范围是0-1,0表示全透明,1表示不透明

    参数interpolationMode:缩放时的插值算法。参数类型是BitmapInterpolationMode枚举,分为Linear和NearestNeighbor

    参数destinationRectangle:在RenderTarget上绘制图像的范围。参数类型是RectF类型。如果不指定的话,默认绘图在原点(左上角),大小是源位图的大小。

    参数sourceRectangle:源位图需要绘制的范围。参数类型是RectF类型。不指定的话,指整个源位图。这个参数可以绘制源位图的一部分。

     

    函数DrawBitmapAtOrigin指的是在原点位置绘制位图,参数意义和上面的一样,这里不再解释了(不过由于不牵涉到缩放操作,似乎参数interpolationMode没什么意义)

     

    从上面的原型定义可以看出,在Direct2D中,有关位图的类是D2DBitmap类。有关位图的操作都和这个有关(绘制位图和位图笔刷(BitmapBrush))。但是,D2DBitmap类没有提供位图和文件转换的函数(从文件读取位图和把位图保存到文件中)。

     

    在Direct2D中,有关位图文件的解码和编码(读取位图文件和保存位图文件)是WIC组件(和Direct2D命名空间平级的WindowsImagingComponent命名空间)

     

    有关WIC(WindowsImagingComponent)组件的介绍如下:

    Windows Imaging Component (WIC) 是 Windows Vista 中用于进行数字成像的扩展平台,它可以作为 .NET Framework 3.0 的部件或能够重新发布的独立组件,也用于 Windows XP 和 Windows Server 2003 中。WIC 在应用程序和 CODEC 之间提供一个抽象层,使应用程序不必专门认知特定的图像格式。无论哪种图像格式,只要机器上装有用于该图像格式的支持 WIC 的 CODEC,任何使用 Windows Imaging Component 的应用程序就能够通过一组一致的接口访问、显示、处理、保存和打印图像。

     

    从上可以看出,WIC(WindowsImagingComponent)组件提供了Direct2D和文件系统的交流平台(Direct2D不必关心位图文件的编码和解码,WIC能自动的把各种格式的位图文件转换为Direct2D认可的位图格式)

     

     

     

    利用WIC在Direct2D中绘制位图文件

     

    由前面的内容可知,Direct2D中只能绘制D2DBitmap对象。

    因此,利用WIC在Direct2D中绘制位图文件的核心内容就是把位图文件转换为D2DBitmap对象。它的操作过程如下:

    1、创建WIC的ImagingFactory类。这个和Direct2D中的D2DFactory类类似。总管类,负责WIC的相关操作。很多的WIC中的类都得依靠它的相关函数才能创建

    2、利用ImagingFactory类的CreateDecoderFromFileName函数,根据位图文件创建BitmapDecoder对象(实际上调用系统解码器解析位图文件)。

          BitmapDecoder对象有1个属性和1个函数

          FrameCount属性:只读属性,说明该位图对象包含的帧数。一般gif文件能包含多个帧,其余格式的一般只有1个帧

          GetFrame函数:返回指定帧对象。参数index是整形,说明是第几帧(从0开始)。返回的是BitmapFrameDecode对象

    3、利用BitmapDecoder对象的GetFrame函数,返回指定帧的BitmapFrameDecode对象。(参数index一般是0,返回第1帧)

          BitmapFrameDecode对象只有1个函数。ToBitmapSource函数。将该对象转换为BitmapSource对象。

     

    一般情况下,到此就可以了。但是,位图格式有很多,你可能不是很确定你的位图格式是否兼容Direct2D的D2DBitmap对象。因此,比较好的做法是继续下面的步骤,将位图格式转换为兼容Direct2D的D2DBitmap对象

     

    4、利用ImagingFactory类的CreateFormatConverter函数创建FormatConverter对象。该对象负责进行格式转换。

    5、调用FormatConverter对象的Initialize方法,进行格式转换。该对象还有一个ToBitmapSource函数。将转换好的位图对象转换为BitmapSource对象。

     

    6、最后,利用RenderTarget对象的CreateBitmapFromWicBitmap函数将之前的BitmapSource对象转换为Direct2D的D2DBitmap对象

     

     

    将Direct2D中的绘图内容保存到位图文件

    前面提到如何在Direct2D中绘制位图文件。那么,反过来,将Direct2D中的绘图内容保存到位图文件也应该是可以的。

    具体的操作过程如下:

    1、利用RenderTarget对象的CreateBitmap函数创建D2DBitmap对象

    2、利用D2DBitmap对象的CopyFromRenderTarget方法将RenderTarget上的内容复制到D2DBitmap对象中

    3、利用WIC中的ImagingFactory类的CreateImagingBitmap函数创建ImagingBitmap对象

    4、利用D2DFactory对象的CreateWicBitmapRenderTarget的函数创建基于ImagingBitmap对象的RenderTarget对象。我们命名为wicRenderTarget,以示区别。

    5、调用wicRenderTarget对象的BeginDraw方法,准备绘图

    6、调用wicRenderTarget对象的DrawBitmap方法,将步骤2中的D2DBitmap对象绘制到wicRenderTarget,实际上是绘制到对应的ImagingBitmap对象。

    7、调用wicRenderTarget对象的EndDraw方法,结束绘图(也可以在步骤6中,利用绘图函数添加自己的水印)

    8、根据要保存文件的后缀名,获得相对应的Guid对象

    9、调用ImagingBitmap对象的SaveToFile方法,将ImagingBitmap中的内容保存到文件中。一共有三个参数:参数imagingFactory,类型是ImagingFactory;参数containerFormat,类型是Guid对象,指明文件的编码方式;参数fileName,要保存的文件名。

     

    需要注意的是,上面的过程中,实际上有两个RenderTarget对象,一个是Direct2D中的RenderTarget和临时创建的wicRenderTarget对象。再利用wicRenderTarget对象的DrawBitmap方法把RenderTarget对象创建的D2DBitmap对象绘制到wicRenderTarget上。这里牵涉到资源共享的问题,在两个(或多个)RenderTarget对象之间共享D2DBitmap对象,则这两个RenderTarget对象创建时的RenderTargetProperties属性中的RenderTargetType的值必须相同(要么是Software,要么是Hardware)。但由于WIC只能是基于Software。因此,如果要用上面的步骤保存到位图文件,则必须把RenderTarget对象的RenderTargetType的值设为Software。但也因此降低了Direct2D的效率。

    RenderTargetType的值有Software(用软件方式呈现绘图)、Hardware(用硬件方式呈现绘图)、Default(由系统判断采用软件还是硬件方式呈现绘图)

     

    下面是读取位图文件和保存位图文件的示例代码:

     
    Imports Microsoft.WindowsAPICodePack.DirectX
    Imports WIC = Microsoft.WindowsAPICodePack.DirectX.WindowsImagingComponent

    Public  Class  clsDirect2DSample10

        Protected _d2DFactory As Direct2D1. D2DFactory
        Protected _renderTarget As Direct2D1. RenderTarget
        Protected _renderProps As Direct2D1. RenderTargetProperties

        Protected _imagingFactory As WIC. ImagingFactory

        Public  Sub  New()
            _d2DFactory = Direct2D1. D2DFactory.CreateFactory()
            _imagingFactory = WIC. ImagingFactory.Create
        End  Sub

        Public  Sub CreateDeviceResource(Target As  Control)
            If _renderTarget Is  Nothing  Then

                _renderProps = New Direct2D1. RenderTargetProperties( _
                                                                Direct2D1. RenderTargetType.Software, _
                                                                New Direct2D1. PixelFormat( _
                                                                                     Graphics. Format.B8G8R8A8UNorm, _
                                                                                     Direct2D1. AlphaMode.Ignore), _
                                                                0, 0, Direct2D1. RenderTargetUsages.None, Direct3D. FeatureLevel.Default)

                _renderTarget = _d2DFactory.CreateHwndRenderTarget( _
                                                          _renderProps, _
                                                          New Direct2D1. HwndRenderTargetProperties( _
                                                                                Target.Handle, _
                                                                                New Direct2D1. SizeU(Target.Width, Target.Height), _
                                                                                Direct2D1. PresentOptions.None) _
                                                          )
            End  If

        End  Sub

        Public  Function LoadBitmapFromFile(fileName As  String, Optional frameIndex As  Integer = 0) As Direct2D1. D2DBitmap
            Dim decoder As WIC. BitmapDecoder = _imagingFactory.CreateDecoderFromFileName( _
                                                                                                   fileName, _
                                                                                                   WIC. DesiredAccess.Read, _
                                                                                                   WIC. DecodeMetadataCacheOption.OnLoad)

            If frameIndex > decoder.FrameCount - 1 OrElse frameIndex < 0 Then frameIndex = 0
            Dim source As WIC. BitmapFrameDecode = decoder.GetFrame(frameIndex)

            Dim converter As WIC. FormatConverter = _imagingFactory.CreateFormatConverter()

            converter.Initialize(source.ToBitmapSource(), WIC. PixelFormats.Pbgra32Bpp, WIC. BitmapDitherType.None, WIC. BitmapPaletteType.MedianCut)

            Return _renderTarget.CreateBitmapFromWicBitmap(converter.ToBitmapSource())

        End  Function

        Public  Sub Render()
            If  Not _renderTarget Is  Nothing  Then

                With _renderTarget
                    .BeginDraw()

                    Dim B As Direct2D1. D2DBitmap = LoadBitmapFromFile( "216.png")

                    .DrawBitmap(B, 1, Direct2D1. BitmapInterpolationMode.Linear, New Direct2D1. RectF(150, 150, 280, 280), New Direct2D1. RectF(0, 0, 260, 260))
                    .DrawBitmapAtOrigin(B, 1, Direct2D1. BitmapInterpolationMode.Linear, New Direct2D1. RectF(10, 10, 130, 130))
                    .EndDraw()
                End  With

                SaveToFile( "217.png")
            End  If
        End  Sub

        Public  Sub SaveToFile(FileName As  String)

            Dim size As Direct2D1. SizeU = _renderTarget.PixelSize
            Dim d2dBitmap As Direct2D1. D2DBitmap = _renderTarget.CreateBitmap(size, _
                                                                                                                 New Direct2D1. BitmapProperties( _
                                                                                                                           New Direct2D1. PixelFormat( _
                                                                                                                                    Graphics. Format.B8G8R8A8UNorm, _
                                                                                                                                    Direct2D1. AlphaMode.Ignore), _
                                                                                                                            _renderTarget.Dpi.X, _renderTarget.Dpi.Y))


            d2dBitmap.CopyFromRenderTarget(_renderTarget)

            Dim wicBitmap As WIC. ImagingBitmap = _imagingFactory.CreateImagingBitmap( _
                                                                                                 size.Width, size.Height, _
                                                                                                 WIC. PixelFormats.Bgr32Bpp, _
                                                                                                 WIC. BitmapCreateCacheOption.CacheOnLoad)
            Dim wicRenderTarget As Direct2D1. RenderTarget = _d2DFactory.CreateWicBitmapRenderTarget(wicBitmap, _renderProps)

            wicRenderTarget.BeginDraw()
            wicRenderTarget.DrawBitmap(d2dBitmap)
            wicRenderTarget.EndDraw()


            Dim fileType As  Guid

            Select  Case FileName.Substring(FileName.LastIndexOf( ".") + 1).ToUpper
                Case  "PNG"
                    fileType = WIC. ContainerFormats.Png
                Case  "JPEG", "JPG"
                    fileType = WIC. ContainerFormats.Jpeg
                Case  "GIF"
                    fileType = WIC. ContainerFormats.Gif
                Case  "TIFF", "TIF"
                    fileType = WIC. ContainerFormats.Tiff
                Case  "WMP"
                    fileType = WIC. ContainerFormats.Wmp
                Case Else
                    fileType = WIC. ContainerFormats.Bmp
            End  Select

            wicBitmap.SaveToFile(_imagingFactory, fileType, FileName)

        End  Sub
    End  Class

    上面的例子中,添加了一个LoadBitmapFromFile函数,负责把位图文件转换为D2DBitmap对象。在LoadBitmapFromFile函数中,一些枚举参数的设置都是采用默认值,最好不要改成其他值。还添加了一个SaveToFile方法,负责把RenderTarget对象上的内容保存到指定文件.

    在Render方法中,先用LoadBitmapFromFile函数加载216.png,然后通过DrawBitmap和DrawBitmapAtOrigin方法绘制图片。并调用SaveToFile方法把RenderTarget上的内容保存到217.png文件中。

     

    先看看216.png图片

    来看看示例代码的效果图,来了解DrawBitmap和DrawBitmapAtOrigin方法的区别

     

     

     

     

    位图笔刷(BitmapBrush)

    在前文介绍了纯色笔刷(SolidColorBrush)、线性渐变笔刷(LinearGradientBrush)、径向渐变笔刷(RadialGradientBrush)

    这里再介绍最后一种笔刷——位图笔刷(BitmapBrush)

     

    先看看位图笔刷(BitmapBrush)对应的RenderTarget对象的CreateBitmapBrush函数的原型定义

     
    Public  Function CreateBitmapBrush(bitmap As Direct2D1. D2DBitmap) As Direct2D1. BitmapBrush
    Public  Function CreateBitmapBrush(bitmap As Direct2D1. D2DBitmap, brushProperties As Direct2D1. BrushProperties) As Direct2D1. BitmapBrush
    Public  Function CreateBitmapBrush(bitmap As Direct2D1. D2DBitmap, bitmapBrushProperties As Direct2D1. BitmapBrushProperties) As Direct2D1. BitmapBrush
    Public  Function CreateBitmapBrush(bitmap As Direct2D1. D2DBitmap, bitmapBrushProperties As Direct2D1. BitmapBrushProperties, brushProperties As Direct2D1. BrushProperties) As Direct2D1. BitmapBrush

    Direct2D1. BitmapBrushProperties(extendModeX As Direct2D1. ExtendMode, extendModeY As Direct2D1. ExtendMode, interpolationMode As Direct2D1. BitmapInterpolationMode)

    从上面的函数的原型定义来看,类型BitmapBrushProperties有三个参数,extendModeX指明位图笔刷(BitmapBrush)在水平扩展区域的扩展模式;extendModeY指明位图笔刷(BitmapBrush)在垂直扩展区域的扩展方式,扩展方式还是有3中,分别是Clamp(延伸:按照笔刷边界点的颜色延伸)、Wrap(换行:按笔刷的方向重新设置颜色)、Mirror(镜像:按笔刷的反方向重新设置颜色)。枚举BitmapInterpolationMode指明位图的插值算法。并且这三个参数在位图笔刷(BitmapBrush)对象中也有对应的属性,分别是ExtendModeX、ExtendModeY、InterpolationMode

     

    我们先看看一个位图笔刷(BitmapBrush)的示例代码

     
    Public  Class  clsDirect2DSample11
        Inherits  clsDirect2DSample

        Protected _imagingFactory As WIC. ImagingFactory

        Public  Sub  New()
            MyBase.New()
            _imagingFactory = WIC. ImagingFactory.Create
        End  Sub

        Public  Function LoadBitmapFromFile(fileName As  String, Optional frameIndex As  Integer = 0) As Direct2D1. D2DBitmap
            Dim decoder As WIC. BitmapDecoder = _imagingFactory.CreateDecoderFromFileName(fileName, WIC. DesiredAccess.Read, WIC. DecodeMetadataCacheOption.OnLoad)
            If frameIndex > decoder.FrameCount - 1 OrElse frameIndex < 0 Then frameIndex = 0
            Dim source As WIC. BitmapFrameDecode = decoder.GetFrame(frameIndex)
            Dim converter As WIC. FormatConverter = _imagingFactory.CreateFormatConverter()
            converter.Initialize(source.ToBitmapSource(), WIC. PixelFormats.Pbgra32Bpp, WIC. BitmapDitherType.None, WIC. BitmapPaletteType.MedianCut)
            Return _renderTarget.CreateBitmapFromWicBitmap(converter.ToBitmapSource())
        End  Function

        Public  Shadows  Sub Render()
            If  Not _renderTarget Is  Nothing  Then

                With _renderTarget
                    .BeginDraw()

                    .Clear( New Direct2D1. ColorF( Color.Chocolate.ToArgb))

                    Dim B As Direct2D1. D2DBitmap = LoadBitmapFromFile( "216.png")
                    Dim BB As Direct2D1. BitmapBrush = _renderTarget.CreateBitmapBrush(B)

                    Dim R As  New Direct2D1. RectF(130, 130, 390, 390)
                    Dim SB As Direct2D1. SolidColorBrush = _renderTarget.CreateSolidColorBrush( New Direct2D1. ColorF(0, 0, 0))

                    .DrawRectangle(R, SB, 3)
                    .FillRectangle(R, BB)

                    .EndDraw()
                End  With
            End  If
        End  Sub
    End  Class

     

    上面的代码中,首先定义了一个位图笔刷(BitmapBrush),然后用该位图笔刷填充一个矩形。下面看看效果

    image

     

    效果有点出乎意料,设置因为,216.png这个位图大小为260*260px,在设置位图笔刷(BitmapBrush)时,默认笔刷的起始位置是画布的原点(左上角)。而由于矩形的范围是(130,130,390,390),因此位图笔刷只有一部分画在矩形的范围里(位图的右下角的部分),而由于默认的扩展模式是Clamp(延伸:按照笔刷边界点的颜色延伸),故在向右和向下延伸了边界的颜色。

     

    如何更改位图笔刷的起始位置?通过位图笔刷(BitmapBrush)的Transform属性来更改起始位置。如下面的示例代码所示(有关Transform的详细内容留待后文再详解)

     
    Public  Class  clsDirect2DSample12
        Inherits  clsDirect2DSample11

        Public  Shadows  Sub Render()
            If  Not _renderTarget Is  Nothing  Then

                With _renderTarget
                    .BeginDraw()

                    .Clear( New Direct2D1. ColorF( Color.Chocolate.ToArgb))

                    Dim B As Direct2D1. D2DBitmap = LoadBitmapFromFile( "216.png")
                    Dim BB As Direct2D1. BitmapBrush = _renderTarget.CreateBitmapBrush(B)

                    BB.Transform = Direct2D1. Matrix3x2F.Translation(130, 130)

                    Dim R As  New Direct2D1. RectF(130, 130, 390, 390)
                    Dim SB As Direct2D1. SolidColorBrush = _renderTarget.CreateSolidColorBrush( New Direct2D1. ColorF(0, 0, 0))

                    .DrawRectangle(R, SB, 3)
                    .FillRectangle(R, BB)

                    .EndDraw()
                End  With
            End  If
        End  Sub
    End  Class

     

    下面是示例代码的效果图,看看效果,了解如何更改位图笔刷(BitmapBrush)的起始位置

    image

     

     

    下面再看看另一个示例的代码,把前面的内容总结复习一下

     
    Public  Class  clsDirect2DSample13
        Inherits  clsDirect2DSample11

        Public  Shadows  Sub Render()
            If  Not _renderTarget Is  Nothing  Then

                With _renderTarget
                    .BeginDraw()

                    .Clear( New Direct2D1. ColorF( Color.Chocolate.ToArgb))

                    Dim PG As Direct2D1. PathGeometry
                    Dim sink As Direct2D1. GeometrySink

                    PG = _d2DFactory.CreatePathGeometry
                    sink = PG.Open

                    sink.BeginFigure( New Direct2D1. Point2F(30, 30), Direct2D1. FigureBegin.Filled)

                    sink.AddLine( New Direct2D1. Point2F(240, 30))
                    sink.AddArc( New Direct2D1. ArcSegment( _
                                                                New Direct2D1. Point2F(240, 240), _
                                                                New Direct2D1. SizeF(60, 100), _
                                                                45, _
                                                                Direct2D1. SweepDirection.Clockwise,
                                                                Direct2D1. ArcSize.Large))
                    sink.AddBezier( New Direct2D1. BezierSegment( _
                                                                        New Direct2D1. Point2F(170, 120), _
                                                                        New Direct2D1. Point2F(100, 360), _
                                                                        New Direct2D1. Point2F(30, 240)))

                    sink.EndFigure(Direct2D1. FigureEnd.Closed)
                    sink.Close()

                    Dim B As Direct2D1. D2DBitmap = LoadBitmapFromFile( "216.png")
                    Dim BB As Direct2D1. BitmapBrush = _renderTarget.CreateBitmapBrush(B)
                    Dim SB As Direct2D1. SolidColorBrush = _renderTarget.CreateSolidColorBrush( New Direct2D1. ColorF(0, 0, 0))

                    BB.ExtendModeX = Direct2D1. ExtendMode.Mirror
                    BB.ExtendModeY = Direct2D1. ExtendMode.Mirror
                    BB.Transform = Direct2D1. Matrix3x2F.Scale(0.4, 0.4)

                    .DrawGeometry(PG, SB, 3)
                    .FillGeometry(PG, BB)

                    .EndDraw()
                End  With
            End  If
        End  Sub
    End  Class

    上面的示例代码中,把位图笔刷(BitmapBrush)的水平扩展模式和垂直扩展模式都改成Mirror(镜像),并且把位图笔刷的大小改为原来的0.4倍。下面看看效果

    image

     

     

     

    最后,介绍一个非常好用的工具:ILSpy。文章中的很多原型定义都是直接从该工具中复制而来,省了不少的功夫。

    posted on 2019-05-05 09:19 NET未来之路 阅读( ...) 评论( ...) 编辑 收藏

    转载于:https://www.cnblogs.com/lonelyxmas/p/10811142.html

    展开全文
  • 关于Direct2D

    千次阅读 2017-09-13 10:54:13
    ㈠ 关于Direct2D  Direct2D是一个硬件加速的,提供立即模式的二维图形API。它提供了二维的几何体,位图,文本的高性能,高质量的渲染。十分方便的是,Direct2D与GDI,GDI+和D3D都是可以交互的。一项技术总是有其...
  • C++ Direct2D绘图、winapi创建窗口初探

    千次阅读 2020-04-20 18:20:48
    1、 什么是Direct2D 一言以蔽之,就是Windows 7平台上的一...Direct2D是基于Direct3D 10.1 API构建的,这意味着Direct2D可以使用硬件加速,下图是Direct2D与Direct3D的一个关系图 由上图可以看出,Direct2D还自...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,733
精华内容 7,493
关键字:

direct2d

友情链接: 23791-g10.zip