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

目前博客园中成系列的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

 

下图是效果图

image

 

 

线性渐变笔刷(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表明该颜色点的颜色。下图很好阐述了这些参数的意义

IC310656

IC310657

 

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

 

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

image

 

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

左上角的矩形中,矩形的范围(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(镜像,下面的矩形)的有趣的示意图。代码就不贴出来了。

image

 

 

径向渐变笔刷(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的集合。

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

IC310659

使用径向渐变笔刷(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

 

下图是示例代码的效果图

image

 

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

posted @ 2013-08-14 15:57  万仓一黍  阅读(3412)  评论(0编辑  收藏  举报