目前博客园中成系列的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. Timer-triggered memory-to-memory DMA transfer demonstrator

    http://www.efton.sk/STM32/bt.c // Timer-triggered memory-to-memory DMA transfer demonstrator for STM ...

  2. bitnami-redmine邮件告警配置

    配置 bitnami-redmine的配置文件与单纯的redmine配置文件可能并不相同,在这里我们需要打开一下配置文件: /opt/bitnami/apps/redmine/htdocs/confi ...

  3. ASP.NET MVC中使用Session来保持表单的状态

    本篇实践在ASP.NET MVC 4下使用Session来保持表单的状态. 本篇的源码在这里: https://github.com/darrenji/KeepFormStateUsingSessio ...

  4. A股和B股票的区别?

    一.A股和B股的区别——概念不同 (一).A股的概念A股是由中国境内的公司发行,正式名称是人民币普通股票,供境内机构.组织或个人(从4月1日起,境内港.澳.台居民可开立A股账户)以人民币认购和交易的普 ...

  5. __NSArrayI removeObjectAtIndex:]: unrecognized selector sent to instance

    同样是删除cell问题,帮我看看问题出现在哪,谢谢! 我的类文件myFile是继承UIViewController的(目的是为了能够在一个view里切换不同的tableView),在myFile.h中 ...

  6. [SQLite][Error Code] 21 misuse

      若使用SQLite API時,出現错误代码21(misuse),可能是你的SQLiteConnection同時打開(Open)了兩個相同的Data source,所造成的错误. 解決方法:检查代码 ...

  7. ios6sdk 和ios7sdk 分别在ios6设备和ios7设备上的效果 对比

  8. 【pycharm】pycharm上安装tensorflow,报错:AttributeError: module 'pip' has no attribute 'main' 解决方法

    pycharm上安装tensorflow,报错:AttributeError: module 'pip' has no attribute 'main' 解决方法 解决方法: 在pycharm的安装目 ...

  9. 解决ADB server didn't ACK问题

    ADB server didn't ACK | 浏览:7400 | 更新:2013-08-11 21:19 1 2 3 4 5 6 7 分步阅读 当我们通过eclipse开发Android应用时,会连 ...

  10. 关于面试总结4-python笔试题

    前言 现在面试测试岗位,一般会要求熟悉一门语言(python/java),为了考验求职者的基本功,一般会出2个笔试题,这些题目一般不难,主要考察基本功. 要是给你一台电脑,在编辑器里面边写边调试,没多 ...