博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Direct2D教程IV——笔刷(Brush)对象
阅读量:4952 次
发布时间:2019-06-11

本文共 10440 字,大约阅读时间需要 34 分钟。

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

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

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

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

 

还有官方的说明文档 ,用的是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

 

下图是示例代码的效果图

 

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

转载于:https://www.cnblogs.com/grenet/p/3256175.html

你可能感兴趣的文章
【VC++积累】之八、PreTranslageMessage;TranslageMessage;GetMessage和PeekMessage的区别
查看>>
置顶结构[置顶] C++中hash map的用法
查看>>
方法类struts2环境搭建
查看>>
文件系统扩容工具
查看>>
HDOJ 1106 排序 (字符串处理)
查看>>
XMLHttpRequest post 传递多个参数及服务器端读取
查看>>
录音函数网络对讲机C#服务器 Android客户端(二) C#服务器代码分析 附加
查看>>
压缩打包linux 文件压缩解压命令Strut2教程-java教程
查看>>
生命的爱
查看>>
学习进度条——第十一周
查看>>
“做教练”之好声音训练
查看>>
SDN第四次作业
查看>>
Oracle创建自增字段方法-ORACLE SEQUENCE的简单介绍
查看>>
[web开发] Vue + spring boot + echart 微博爬虫展示平台
查看>>
LeetCode-176:第二高的薪水
查看>>
Excel Service 外部数据实时性配置说明
查看>>
log4net 日志配置及使用
查看>>
Js调用本地程序
查看>>
How to build python3.3 using Visual Studio 2012 Ultimate
查看>>
Aciidoc 中的"++"符号
查看>>