目前博客园中成系列的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. tomcat开启SSL8443端口的方法

    参考文献: http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html http://blog.sina.com.cn/s/blog_682b5aa1 ...

  2. asp.net MVC 中 Session统一验证的方法

    验证登录状态的方法有:1  进程外Session   2 方法过滤器(建一个类继承ActionFilterAttribute)然后给需要验证的方法或控制器加特性标签 3 :新建一个BaseContro ...

  3. SOC 与 ARM

    SOC是指片上系统,意思是一个芯片就构成一个包括了存储.CPU.甚至还有AD.UART等等其他资源的系统!而ARM只是CPU的一种,有的片上系统是51.nios.PIC.等等不一而是!特别是nios, ...

  4. 推荐一个文献翻译软件--Deja Vu X

    首先我的这篇博客推荐的软件并非你觉得翻译精确度有多高的软件,假设是这种话就不用往下看了,免得浪费时间,仅仅是一个对于翻译文献非常方便的工具,方面在哪请看下文. 我是不会告诉你凡事用过这个软件的人都说好 ...

  5. CentOS 安装 Redis (高可用)

    原文:https://www.sunjianhua.cn/archives/centos-redis.html 下载地址: http://download.redis.io/releases/ 官方文 ...

  6. self.xxx = nil 可以等效于[_xxx release] _xxx= nil 么

    如果属性是copy.retain的话是等价的.如下: - (void)setXXX:(NSString*)axx { if (_xxx != axx) { [_xxx release]; _xxx = ...

  7. WordPress主题开发:加载脚本和样式

    如果只引入style.css,我把这个放头顶就可以了 <link rel="stylesheet" href="<?php echo get_styleshe ...

  8. Linux 内核网络协议栈 ------sk_buff 结构体 以及 完全解释 (2.6.16)

    转自:http://blog.csdn.net/shanshanpt/article/details/21024465 在2.6.24之后这个结构体有了较大的变化,此处先说一说2.6.16版本的sk_ ...

  9. Java锁的设计

    1.自旋锁 自旋锁是采用让当前线程不停地的在循环体内执行实现的,当循环的条件被其他线程改变时 才能进入临界区.如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public ...

  10. 《Google Glass开发指南》

    <Google Glass开发指南> 基本信息 作者: BestApp工作室 丛书名: 图灵原创 出版社:人民邮电出版社 ISBN:9787115349477 上架时间:2014-3-19 ...