目前博客园中成系列的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中不再区分笔刷(Brush)对象和画笔(Pen)对象,统一用笔刷(Brush)对象。这样,在绘制时候,无论是以Draw开头的函数还是以Fill开头的函数都使用笔刷(Brush)对象。

在Direct2D中,RenderTarget对象相当于画布,Geometry等(还有文字、图像等对象)对象相当于绘画的内容,而Brush对象相当于绘画的工具。使用Direct2D就是用工具把内容画到画布上。本文就详细介绍笔刷(Brush)对象

Direct2D中的笔刷(Brush)的类型

纯色笔刷(SolidColorBrush):使用一种颜色的笔刷。用一种颜色绘制内容。

线性渐变笔刷(LinearGradientBrush):使用两种或多种颜色且是线性渐变的笔刷。用线性渐变的颜色填充需要绘制的区域

径向渐变笔刷(RadialGradientBrush):使用两种或多种颜色且是径向渐变的笔刷。用径向渐变的颜色填充需要绘制的区域

位图笔刷(BitmapBrush):使用位图的笔刷。用位图填充需要绘制的区域

本文主要介绍前三种笔刷,位图笔刷(BitmapBrush)留待后文详解

纯色笔刷(SolidColorBrush)

在Direct2D中,所有的笔刷(Brush)对象都继承自类Brush,纯色笔刷(SolidColorBrush)也不例外。笔刷(Brush)对象不能独自实例化,必须通过RenderTarget对象的对应的函数创建而成。纯色笔刷(SolidColorBrush)是由RenderTarget对象的CreateSolidColorBrush函数创建而成。

来看看CreateSolidColorBrush函数的原型定义

 
Public Function CreateSolidColorBrush(color As Direct2D1.ColorF) As Direct2D1.SolidColorBrush
Public Function CreateSolidColorBrush(color As Direct2D1.ColorF, brushProperties As Direct2D1.BrushProperties) As Direct2D1.SolidColorBrush

CreateSolidColorBrush函数的原型定义中,传入一个ColorF的参数和BrushProperties参数

在Direct2D中,用结构ColorF表示颜色,它有四个分量,分别是Red、Green、Blue表示三种颜色的分量和Alpha表示不透明度的分量,分量的取值范围在0-1之间。

还有一个结构ColorI也表示颜色,和ColorF类似,只是分量的范围在0-255之间的整数。在实际使用中,ColorI仅仅起到辅助作用,最后还是要转换为ColorF。

来看看结构ColorF的构造函数的原型定义

 
Direct2D1.ColorF(red As Single, green As Single, blue As Single)
Direct2D1.ColorF(red As Single, green As Single, blue As Single, alpha As Single)
Direct2D1.ColorF(argb As Integer)
Direct2D1.ColorF(colorValues As Single(), alpha As Single)
Direct2D1.ColorF(colorValues As Single())
Direct2D1.ColorF(color As Direct2D1.ColorI)

上面的原型定义中,如果不指定参数alpha,则分量Alpha默认值是1。

在第三个函数中,可以通过系统中的Color结构获得某些系统指定的颜色。例如:Direct2D1.ColorF(Color.Aqua.ToArgb())获得系统中名为Aqua的颜色。需要注意的是,如果是手动传入参数的话,得是8位的16进制的数,每2位表示一个分量,例如:&HFF9ACD32

第四个和第五个函数中的数组中元素数不能少于3个。第五个函数数组元素数是4个的话,第四个元素指的是Alpha分量,如果元素数不是4个(3、5等其他值),则Alpha分量为1。

再看看结构BrushProperties的构造函数的原型定义

 
Direct2D1.BrushProperties(opacity As Single, transform As Direct2D1.Matrix3x2F)

参数opacity指的是不透明度,参数transform指的是变换矩阵。不过BrushProperties对纯色笔刷(SolidColorBrush)没啥太大的用处。貌似该参数仅仅对位图笔刷(BitmapBrush)有用,而其他的笔刷则通过构造函数能完成该参数实现的效果。

下面是纯色笔刷(SolidColorBrush)的示例,先用RenderTarget对象的clear方法(白色)清除画布,再用黑色描边,用绿色(&HFF9ACD32)填充

 
Public Class clsDirect2DSample6
    Inherits clsDirect2DSample

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

With _renderTarget
                .BeginDraw()

Dim B As Direct2D1.SolidColorBrush = _renderTarget.CreateSolidColorBrush(New Direct2D1.ColorF(Color.Black.ToArgb))
                Dim FB As Direct2D1.SolidColorBrush = _renderTarget.CreateSolidColorBrush(New Direct2D1.ColorF(&HFF9ACD32))

Dim R As New Direct2D1.RectF(30, 30, 200, 200)

.Clear(New Direct2D1.ColorF(1, 1, 1))

.DrawRectangle(R, B, 3)
                .FillRectangle(R, FB)

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

下图是效果图

线性渐变笔刷(LinearGradientBrush)

自GDI+开始,就引入了扩展笔刷(线性渐变笔刷(LinearGradientBrush)、径向渐变笔刷(RadialGradientBrush)、位图笔刷(BitmapBrush))。

线性渐变笔刷(LinearGradientBrush)就像是PS中的“渐变工具”

我们回顾下如何在PS中使用“渐变工具”

先是在渐变编辑器界面中,设置渐变颜色,如下图

然后在画布上,用渐变工具拖动(相当于设置渐变效果的起点和终点)完成渐变效果

线性渐变笔刷(LinearGradientBrush)也是类似的,先要完成渐变颜色的设置,然后设置笔刷的起点和终点。才能正常使用该笔刷。

先看看线性渐变笔刷(LinearGradientBrush)对应的RenderTarget对象的CreateLinearGradientBrush函数的原型定义

 
Public Function CreateLinearGradientBrush( _
                                                             linearGradientBrushProperties As Direct2D1.LinearGradientBrushProperties, _
                                                             gradientStopCollection As Direct2D1.GradientStopCollection _
                                                           ) As Direct2D1.LinearGradientBrush
Public Function CreateLinearGradientBrush( _
                                                             linearGradientBrushProperties As Direct2D1.LinearGradientBrushProperties, _
                                                             gradientStopCollection As Direct2D1.GradientStopCollection, _
                                                             brushProperties As Direct2D1.BrushProperties _
                                                           ) As Direct2D1.LinearGradientBrush

Public Sub Direct2D1.LinearGradientBrushProperties(startPoint As Direct2D1.Point2F, endPoint As Direct2D1.Point2F)
Public Sub Direct2D1.GradientStop(position As Single, color As Direct2D1.ColorF)

从上面的函数的原型定义来看,主要是传递了两个参数:一是LinearGradientBrushProperties结构,定义了该笔刷的起点和终点(在画布上的位置);二是GradientStopCollection类,包含了一个GradientStop的集合。每个GradientStop对象表示渐变轴上的一个颜色点,从GradientStop的原型定义来看,传递了两个参数,position表明渐变轴上颜色点的位置,范围是0-1,0表示起点的颜色,1表示终点的颜色;color表明该颜色点的颜色。下图很好阐述了这些参数的意义

GradientStopCollection对象也必须依靠RenderTarget对象的CreateGradientStopCollection函数创建,下面看看CreateGradientStopCollection函数的原型定义

 
Public Function CreateGradientStopCollection( _
                                                                gradientStops As IEnumerable(Of Direct2D1.GradientStop), _
                                                           colorInterpolationGamma As Direct2D1.Gamma, _
                                                                extendMode As Direct2D1.ExtendMode _
                                                             ) As Direct2D1.GradientStopCollection
Public Enum Gamma
    Linear = 1
    StandardRgb = 0
End Enum

Public Enum ExtendMode
    Mirror = 2
    Wrap = 1
    Clamp = 0
End Enum

该原型定义中,参数gradientStops表示一个GradientStop集合,每个GradientStop表示渐变轴上的一个颜色点。参数colorInterpolationGamma是枚举Gamma,表示两种颜色间的插值算法,可以试试两种算法之间的差异。

参数extendMode是枚举ExtendMode,表示超出笔刷范围外的扩展模式,有Clamp(延伸:按照笔刷边界点的颜色延伸)、Wrap(换行:按笔刷的方向重新设置颜色)、Mirror(镜像:按笔刷的反方向重新设置颜色),在下面的示例中,我们看看这几个扩展模式的区别

使用线性渐变笔刷(LinearGradientBrush)步骤

1、创建GradientStop集合,并添加若干GradientStop

2、创建GradientStopCollection对象

2、创建LinearGradientBrushProperties,设置线性渐变的起点、终点

3、利用步骤2和步骤3创建的对象创建线性渐变笔刷(LinearGradientBrush)

下面是示例代码

 
Public Class clsDirect2DSample7
    Inherits clsDirect2DSample

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

With _renderTarget
                .BeginDraw()

Dim B As Direct2D1.SolidColorBrush = _renderTarget.CreateSolidColorBrush(New Direct2D1.ColorF(Color.Black.ToArgb))
                Dim LGB As Direct2D1.LinearGradientBrush

Dim G As New List(Of Direct2D1.GradientStop)
                G.Add(New Direct2D1.GradientStop(0, New Direct2D1.ColorF(Color.Yellow.ToArgb)))
                G.Add(New Direct2D1.GradientStop(1, New Direct2D1.ColorF(Color.ForestGreen.ToArgb)))

Dim GS As Direct2D1.GradientStopCollection
                Dim R As Direct2D1.RectF
                Dim LP As Direct2D1.LinearGradientBrushProperties

.Clear(New Direct2D1.ColorF(1, 1, 1))

R = New Direct2D1.RectF(30, 30, 190, 190)
                LP = New Direct2D1.LinearGradientBrushProperties(New Direct2D1.Point2F(30, 30), New Direct2D1.Point2F(190, 190))
                GS = _renderTarget.CreateGradientStopCollection(G, Direct2D1.Gamma.StandardRgb, Direct2D1.ExtendMode.Clamp)
                LGB = _renderTarget.CreateLinearGradientBrush(LP, GS)

.DrawRectangle(R, B, 3)
                .FillRectangle(R, LGB)

R = New Direct2D1.RectF(250, 30, 410, 190)
                LP = New Direct2D1.LinearGradientBrushProperties(New Direct2D1.Point2F(250, 30), New Direct2D1.Point2F(330, 110))
                GS = _renderTarget.CreateGradientStopCollection(G, Direct2D1.Gamma.StandardRgb, Direct2D1.ExtendMode.Clamp)
                LGB = _renderTarget.CreateLinearGradientBrush(LP, GS)

.DrawRectangle(R, B, 3)
                .FillRectangle(R, LGB)

R = New Direct2D1.RectF(30, 250, 190, 410)
                LP = New Direct2D1.LinearGradientBrushProperties(New Direct2D1.Point2F(30, 250), New Direct2D1.Point2F(110, 330))
                GS = _renderTarget.CreateGradientStopCollection(G, Direct2D1.Gamma.StandardRgb, Direct2D1.ExtendMode.Wrap)
                LGB = _renderTarget.CreateLinearGradientBrush(LP, GS)

.DrawRectangle(R, B, 3)
                .FillRectangle(R, LGB)

R = New Direct2D1.RectF(250, 250, 410, 410)
                LP = New Direct2D1.LinearGradientBrushProperties(New Direct2D1.Point2F(250, 250), New Direct2D1.Point2F(330, 330))
                GS = _renderTarget.CreateGradientStopCollection(G, Direct2D1.Gamma.StandardRgb, Direct2D1.ExtendMode.Mirror)
                LGB = _renderTarget.CreateLinearGradientBrush(LP, GS)

.DrawRectangle(R, B, 3)
                .FillRectangle(R, LGB)

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

下图是示例代码的运行效果图

上图中,先设置了一个从黄色到绿色的线性渐变。

左上角的矩形中,矩形的范围(30,30,190,190),渐变的起点是(30,30)、终点(190,190),渐变从矩形的左上角到矩形的右下角

右上角的矩形中,矩形的范围(250,30,410,190),渐变的起点是(250,30)、终点(330,110),矩形以对角线为界,上面是渐变部分,下面是扩展部分。扩展模式设置为Clamp(延伸),扩展部分的颜色就是渐变边界(对角线)的颜色

左下角的矩形中,矩形的范围(30,250,190,410),渐变的起点是(30,250)、终点(110,330),矩形以对角线为界,上面是渐变部分,下面是扩展部分。扩展模式设置为Wrap(换行),扩展部分的颜色就是重新开始的一个渐变(渐变方向不变)

右下角的矩形中,矩形的范围(250,250,410,410),渐变的起点是(250,250)、终点(330,330),矩形以对角线为界,上面是渐变部分,下面是扩展部分。扩展模式设置为Mirror(镜像),扩展部分的颜色就是重新开始的一个渐变(渐变方向改变)

下图是扩展模式分别为Wrap(换行,上面的矩形)和Mirror(镜像,下面的矩形)的有趣的示意图。代码就不贴出来了。

径向渐变笔刷(RadialGradientBrush)

径向渐变和线性渐变类似,都是颜色的渐变,只不过径向的渐变是以椭圆为基准,起点是椭圆的内部点(一般是中心),终点是椭圆的边界,椭圆边界外部的区域为扩展区域。

先看看径向渐变笔刷(RadialGradientBrush)对应的RenderTarget对象的CreateRadialGradientBrush函数的原型定义

 
Public Function CreateRadialGradientBrush( _
                                                            radialGradientBrushProperties As Direct2D1.RadialGradientBrushProperties, _
                                                            gradientStopCollection As Direct2D1.GradientStopCollection _
                                                           ) As Direct2D1.RadialGradientBrush
Public Function CreateRadialGradientBrush( _
                                                            radialGradientBrushProperties As Direct2D1.RadialGradientBrushProperties, _
                                                            gradientStopCollection As Direct2D1.GradientStopCollection, _
                                                            brushProperties As Direct2D1.BrushProperties _
                                                           ) As Direct2D1.RadialGradientBrush

Direct2D1.RadialGradientBrushProperties(center As Direct2D1.Point2F, gradientOriginOffset As Direct2D1.Point2F, radiusX As Single, radiusY As Single)

从上面的函数的原型定义来看,主要是传递了两个参数:一是RadialGradientBrushProperties结构,定义了该笔刷的中心点(椭圆的中心点)、偏移点(相对中心点的位置)和椭圆的横轴半径和纵轴半径;二是GradientStopCollection类,包含了一个GradientStop的集合。

下图阐述了偏移点对径向渐变笔刷的影响

使用径向渐变笔刷(RadialGradientBrush)步骤

1、创建GradientStop集合,并添加若干GradientStop

2、创建GradientStopCollection对象

2、创建RadialGradientBrushProperties,设置径向渐变的中心点、偏移点、横轴半径、纵轴半径等

3、利用步骤2和步骤3创建的对象创建线性渐变笔刷(RadialGradientBrush)

下面是示例代码,偏移点设置为中心点的(-50,-50)处

 
Public Class clsDirect2DSample9
    Inherits clsDirect2DSample

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

With _renderTarget
                .BeginDraw()

Dim B As Direct2D1.SolidColorBrush = _renderTarget.CreateSolidColorBrush(New Direct2D1.ColorF(Color.Black.ToArgb))

Dim G As New List(Of Direct2D1.GradientStop)
                G.Add(New Direct2D1.GradientStop(0, New Direct2D1.ColorF(0.9, 0.9, 0.9)))
                G.Add(New Direct2D1.GradientStop(1, New Direct2D1.ColorF(Color.ForestGreen.ToArgb)))

Dim GS As Direct2D1.GradientStopCollection
                Dim RGB As Direct2D1.RadialGradientBrush
                Dim RP As Direct2D1.RadialGradientBrushProperties

.Clear(New Direct2D1.ColorF(1, 1, 1))

RP = New Direct2D1.RadialGradientBrushProperties(New Direct2D1.Point2F(200, 200), New Direct2D1.Point2F(-50, -50), 120, 120)
                GS = _renderTarget.CreateGradientStopCollection(G, Direct2D1.Gamma.StandardRgb, Direct2D1.ExtendMode.Clamp)
                RGB = _renderTarget.CreateRadialGradientBrush(RP, GS)

Dim E As New Direct2D1.Ellipse(New Direct2D1.Point2F(200, 200), 120, 120)

.Clear(New Direct2D1.ColorF(1, 1, 1))

.DrawEllipse(E, B, 3)
                .FillEllipse(E, RGB)

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

下图是示例代码的效果图

合理的运用各种笔刷,能实现各种效果,就看你们自己的想象发挥了。

Direct2D教程IV——笔刷(Brush)对象的更多相关文章

  1. Direct2D教程V——位图(Bitmap)和位图笔刷(BitmapBrush)

    目前博客园中成系列的Direct2D的教程有 1.万一的 Direct2D 系列,用的是Delphi 2009 2.zdd的 Direct2D 系列,用的是VS中的C++ 3.本文所在的 Direct ...

  2. Direct2D教程VIII——几何(Geometry)对象的运算,本系列的终结篇

    目前博客园中成系列的Direct2D的教程有 1.万一的 Direct2D 系列,用的是Delphi 2009 2.zdd的 Direct2D 系列,用的是VS中的C++ 3.本文所在的 Direct ...

  3. Direct2D教程VII——变换几何(TransformedGeometry)对象

    目前博客园中成系列的Direct2D的教程有 1.万一的 Direct2D 系列,用的是Delphi 2009 2.zdd的 Direct2D 系列,用的是VS中的C++ 3.本文所在的 Direct ...

  4. Direct2D教程VI——转换(Transform)

    目前博客园中成系列的Direct2D的教程有 1.万一的 Direct2D 系列,用的是Delphi 2009 2.zdd的 Direct2D 系列,用的是VS中的C++ 3.本文所在的 Direct ...

  5. 创建Brush对象

    在GDI+中,可使用笔刷,以各种个颜色和图像填充图形,GDI+的Brush类本身是一个抽象的类,所以是不能实例化Brush的 但是GDI+的API提供五个类,就扩展了Brush类并提供了具体的实现方式 ...

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

    目前博客园中成系列的Direct2D的教程有 1.万一的 Direct2D 系列,用的是Delphi 2009 2.zdd的 Direct2D 系列,用的是VS中的C++ 3.本文所在的 Direct ...

  7. Customize Acrylic Brush in UWP Applications(在UWP中自定义亚克力笔刷)

    原文 Customize Acrylic Brush in UWP Applications(在UWP中自定义亚克力笔刷) Windows 10 Fall Creators Update(Build ...

  8. Vegas教程分享,制作古装墨迹笔刷开场效果

    许多酷炫的古装大片,片头曲介绍人物的时候,都有一种墨迹笔刷的开场效果,那么这个特效如何利用Vegas去做呢? 1.导入素材文件 首先呢,导入相关文件素材到视频制作软件Vegas中,点击页面上方如图1箭 ...

  9. 2019-8-30-C#-从零开始写-SharpDx-应用-笔刷

    title author date CreateTime categories C# 从零开始写 SharpDx 应用 笔刷 lindexi 2019-8-30 8:50:0 +0800 2019-6 ...

随机推荐

  1. There are no packages available for install

    解决方法: ·删除sublime Text 安装目录下Data->Packages目录下的Package Control(如果没有,略过此步骤). ·下载Package Control,下载路径 ...

  2. error: internal error: unable to execute QEMU command 'migrate': this feature or command is not cur

    感谢朋友支持本博客,欢迎共同探讨交流,因为能力和时间有限.错误之处在所难免,欢迎指正. 假设转载.请保留作者信息. 博客地址:http://blog.csdn.net/qq_21398167 原博文地 ...

  3. smartsvn学习(一)Xcode下svn客户端使用指南

    http://smartsvn.com/features 说明 场景 执行步骤 创建新项目 一,二,三,四 下载项目 一,二,四 代码提交 五 代码更新 六 一,打开SCM 在xcode中,点击菜单: ...

  4. 【SVN】如果windows用户忘记了svn的用户名和密码怎么办?

    如果windows用户忘记了svn的用户名和密码怎么办? 1>你得进入默认地址 C:\Users\Administrator\AppData\Roaming\Subversion\auth\sv ...

  5. cocos2d-x 3.0 正式版 项目创建

    官方示比例如以下: Example: $ cd cocos2d-x $ ./setup.py $ source FILE_TO_SAVE_SYSTEM_VARIABLE $ cocos new Eng ...

  6. struct net_device网络设备结构体详解

    转自:http://blog.csdn.net/viewsky11/article/details/53046787 在linux中使用struct net_device结构体来描述每一个网络设备.同 ...

  7. POST 和 PUT 方法区别

        Http定义了与 服务器的交互方法,其中除了一般我们用的最多的GET,POST 其实还有PUT和DELETE 根据RFC2616标准(现行的HTTP/1.1)其实还有OPTIONS,GET,H ...

  8. 罪恶黑名单第一季/全集The Blacklist迅雷下载

    罪恶黑名单 第一季 The Blacklist Season 1 (2013)本季看点:几十年来,绰号「红魔」(Red)的前军事情报官员Raymond Reddington(James Spader) ...

  9. 自己写的SeekBarPreference,可以实现seekbar滑动监听和设置默认进度和最大进度

    我通过参考android源码,把这个烂尾的类写完了.具体实现了seekbar的数据自动存储,seekbar拖动时触发监听器,可以设置默认的进度和最大进度.先说使用的方式: 1.在xml文件中使用pre ...

  10. 深入理解java虚拟机(六)字节码指令简介

    Java虚拟机指令是由(占用一个字节长度.代表某种特定操作含义的数字)操作码Opcode,以及跟随在其后的零至多个代表此操作所需参数的称为操作数 Operands 构成的.由于Java虚拟机是面向操作 ...