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

 

合理的運用各種筆刷,能實現各種效果,就看你們自己的想象發揮了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM