C#應用程序設計教程(第2版)第05章-WPF圖形圖像編程_第1頁
C#應用程序設計教程(第2版)第05章-WPF圖形圖像編程_第2頁
C#應用程序設計教程(第2版)第05章-WPF圖形圖像編程_第3頁
C#應用程序設計教程(第2版)第05章-WPF圖形圖像編程_第4頁
C#應用程序設計教程(第2版)第05章-WPF圖形圖像編程_第5頁
已閱讀5頁,還剩148頁未讀, 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第五章WPF圖形圖像編程能夠使用WPF技術編寫圖形圖像程序掌握三類繪制圖形的方法掌握畫筆、畫刷繪圖形工具能夠進行圖形變換能夠如何處理圖像和剪貼板了解WPF3D圖形學習目的主要內容5.1WPF和GDI5.2常用的結構5.3使用Shape派生類5.4使用Drawing派生類5.5使用Visual類派生類5.6Pen類和Brush類5.7圖形變換5.8位圖效果5.9處理圖像5.10圖像剪貼板功能5.113D圖形5.12DirectX3D和XNA介紹

5.1WPF和GDIWPF和GDI的圖形圖像編程方法有很大不同。GDI一般采用即時模式顯示圖形和圖像,當窗口圖形和圖像被破壞后,程序員要自己在OnPaint事件處理函數中恢復被破壞的圖形和圖像。而WPF采用保留模式顯示圖像,一般由WPF系統自己恢復被破壞的圖形和圖像。WPF控件外觀一般用矢量圖形實現,控件能夠記錄生成控件矢量圖形的方法,當外觀需要恢復時自動調用這些方法重現自己外觀。這樣做的好處是圖形外觀和顯示器分辨率無關,能夠自適應不同分辨率顯示器。WPF提供了三類顯示圖形的方法,它們是:System.Windows.Shapes.Shape類派生類:這些類都是控件,設置必要的屬性,就可以繪制所需要的圖形。這類控件最容易使用,但是由于這些控件支持布局和數據綁定等功能,能夠響應較多的事件,使用這些控件將會大大增加應用程序的資源消耗,一般只用來在窗口顯示少量的圖形。System.Windows.Media.Drawing類派生類:這些類都支持XAML,能夠實現Shape類派生類相同的功能。這類控件只支持少量的事件及少量的功能,使用這類控件將能極大減少資源消耗,相對于Shape類派生類要寫較多的XAML標記。System.Windows.Media.Visual類派生類:這些類對XAML支持有限,繪制圖形方法類似GDI+,一般要編寫大量的代碼,使用類的方法繪制圖形,其占用的資源最少5.2常用的結構5.2.1Point和Size結構點結構System.Windows.Point定義點的位置,點結構有兩個成員:X,Y,表示點的x軸和y軸的坐標。其構造函數如下:publicPoint(doublex,doubley)System.Windows.Size結構用屬性Width和Height描述對象寬和高。其構造函數如下:publicSize(doublewidth,doubleheight)

5.2.2Rect結構矩形結構System.Windows.Rect,用來描述一個矩形,其常用屬性和方法如下:屬性X、Y:矩形結構左上角的x、y坐標。只讀屬性Left、Top:矩形結構左上角的x、y坐標。只讀屬性Right和Bottom:矩形結構對象右下角的x坐標和y坐標。屬性Width、Height和Size:矩形結構對象的寬度和高度。構造函數Rect(Pointlocation,Sizesize):參數1代表矩形結構左上角點結構,參數2是表示代表矩形寬和高的Size結構。構造函數Rect(Doublex,Doubley,Doublewidth,Doubleheight):參數依次為矩形左上角x坐標、y坐標、寬和高。還有其他三個構造函數,請參考幫助系統有關內容。靜態方法publicstaticRectIntersect(Rectrect1,Rectrect2):返回Rect結構,是兩個參數表示的矩形結構的交集。如果沒有交集,則返回空。交集概念見5.4.4節。方法publicvoidIntersect(Rectrect):得到調用該方法的矩形結構對象和參數表示的矩形結構的交集。靜態方法publicstaticRectUnion(Rectrect1,Rectrect2):返回Rect結構,是兩個參數表示的矩形結構的并集。并集概念見5.4.4節。參數2也可為Point。方法publicboolContains(Point或Rect):判斷參數表示的點或矩形結構是否在調用該方法的矩形結構對象中。5.2.3Color結構System.Windows.Media.Color結構用來表示顏色。任何一種顏色可以用透明度(a),藍色(b),綠色(g),紅色(r)合成。Color結構支持兩種色彩空間sRGB和scRGB。sRGB用無符號32位數代表一種顏色,紅色、綠色、藍色以及透明度各占一個字節,透明度等于0為完全透明,255為完全不透明,完全不透明紅色用16進制數表示為:#ffff0000。scRGB代表的顏色中的紅色、綠色、藍色以及透明度分別用0-1之間的Single類型數表示,透明度等于0.0為完全透明,1.0為完全不透明,紅色、綠色、藍色全為0.0表示黑色,全為1.0表示白色,不透明紅色表示為:sc#1.0,1.0,0.0,0.0。其常用屬性和方法如下:屬性R、G、B和A:分別表示sRGB空間的紅色、綠色、藍色以及透明度。屬性scR、scG、scB和scA:分別表示scRGB空間的紅色、綠色、藍色以及透明度。publicstaticColorFromRgb(byter,byteg,byteb):得到不透明sRGB顏色。publicstaticColorFromArgb(bytea,byter,byteg,byteb):sRGB顏色。publicstaticColorFromScRgb(floata,floatr,floatg,floatb):scRGB顏色。publicstaticboolAreClose(Colorcolor1,Colorcolor2):由于scRGB顏色可能無法完全相等,用此函數比較兩個scRGB顏色是否近似相等。5.3使用Shape派生類Shape派生類包括畫線段控件Line、畫矩形控件Rectangle、畫圓或橢圓控件Ellipse、畫多條線段控件Polyline、畫由多條線段組成的閉合圖形控件Polygon和畫任意曲線控件Path。5.3.1公用屬性

Fill:Brush類對象,指定封閉圖像的填充顏色。Stroke:Brush類對象,指定線的顏色或封閉圖形外輪廓線的顏色。StrokeThickness:指定線的寬度或封閉圖形外輪廓線的寬度。GeometryTransform:對圖形位置進行變換。5.3.2畫線控件Line控件Line用來畫線段,屬性X1和Y1為線段起點,屬性X2和Y2為線段終點。

【例5.1】畫一條線段的XAML標記如下,注意實際程序必須添加省略的標記。<Grid><!--Window標記及其一些屬性被省略,正式程序必須保留--><LineX1="0"Y1="0"X2="100"Y2="100"Stroke="Black"StrokeThickness="10"/></Grid>5.3.3畫矩形控件Rectangle控件Rectangle可用來畫各種矩形,屬性Width、Height、RadiusX和RadiusY分別是矩形的寬、高、圓角矩形的圓角x軸半徑和y軸半徑。x軸半徑要小于等于Width二分之一,y軸半徑要小于等于Height二分之一,當二者都等于二分之一,則圖形變為圓或橢圓?!纠?.2】畫矩形和圓角矩形的XAML標記如下,如果Width=Height,為正方形。<Grid><RectangleWidth="100"Height="50"Fill="Blue"Stroke="Black"StrokeThickness="4"><Rectangle.RenderTransform><RotateTransformCenterX="0"CenterY="0"Angle="-45"/></Rectangle.RenderTransform></Rectangle><RectangleMargin="0,150,0,0"Width="100"Height="50"Fill="Blue"RadiusX="20"RadiusY="20"/></Grid>【例5.3】用代碼生成矩形,為Grid控件添加屬性Name="grid1",在窗體增加按鈕,其事件函數如下,單擊按鈕,則出現一個黑輪廓線,內部填充天藍色的正方形。privatevoidbutton1_Click(objectsender,RoutedEventArgse){RectanglemyRect=newRectangle();myRect.Stroke=Brushes.Black;myRect.Fill=Brushes.SkyBlue;myRect.Height=50;myRect.Width=50;RotateTransformrotateTransform1=newRotateTransform(-45);myRect.RenderTransform=rotateTransform1;grid1.Children.Add(myRect);}【例5.4】繪制3個重疊的矩形,演示透明效果。將如下標記放到Grid標記中。請讀者仔細分析運行后不同位置為什么會產生相應顏色。<GridWidth="200"Height="200"><RectangleFill="#ff0000ff"Margin="0,0,50,50"/> <!--顏色不透明--><RectangleFill="#80ff0000"Margin="50,0,0,50"/> <!--顏色半透明--><RectangleFill="#8000ff00"Margin="25,50,25,0"/> <!--顏色半透明--></Grid>5.3.4畫圓或橢圓控件Ellipse控件Ellipse畫橢圓時如果Width=Height,則為圓?!纠?.5】本例用鍵盤4個箭頭鍵推動一個紅色圓,可以在窗體的4個方向上移動,當圓到了窗體邊界,圓就不能繼續移動了。(1)創建WPF項目。放置Ellipse控件到Grid面板,拖動Ellipse控件向左上方移動,一直到只有左方和上方的兩根指示距離邊界的線(圖5.1),修改Ellipse控件的控制邊界顏色屬性Stroke="Red",控制填充顏色屬性Fill="Red"。此時Ellipse控件XAML標記如下:<EllipseMargin="37,22,0,0"Name="ellipse1"Stroke="Red"Fill="Red"HorizontalAlignment="Left"Width="100"Height="100"VerticalAlignment="Top"/>

(2)選中Window1窗體,為其增加KeyDown事件函數如下:privatevoidWindow_KeyDown(objectsender,KeyEventArgse){doublex1=ellipse1.Margin.Left;doublex2=ellipse1.Margin.Top;switch(e.Key){caseKey.Left:if(ellipse1.Margin.Left>0)x1-=1;break;caseKey.Right:if((ellipse1.Margin.Left+100)<this.Width)x1+=1;break;

caseKey.Down:if(ellipse1.Margin.Top+100<this.Height)x2+=1;break;caseKey.Up:if(ellipse1.Margin.Top>0) x2-=1;break;}ellipse1.Margin=newThickness(x1,x2,0,0);}(3)運行,可以用4個箭頭鍵移動紅色圓。【例5.6】Windows畫圖程序用拖動鼠標方法畫橢圓或圓,實現的方法是以鼠標左鍵單擊處作為矩形的一個頂點,記為頂點1,該點坐標不改變。拖動鼠標移動到另一位置,以此位置作為矩形另一頂點,記為頂點2,頂點1和頂點2在矩形對角線的兩端。繪制由頂點1和頂點2定義的矩形的內切橢圓,以顯示要繪制橢圓的位置,這個橢圓的位置隨著鼠標的移動而改變。鼠標抬起,以鼠標抬起位置為頂點2,用指定的顏色繪制由頂點1和頂點2定義的矩形的內切橢圓,作為最終圖形。具體步驟如下。(1)創建WPF項目。放置Ellipse控件到<grid>面板中,拖動Ellipse控件向左上方移動,一直到只有左方和上方的兩根指示距離邊界的線。此時Ellipse控件XAML標記見例5.5。(2)為<grid>面板增加名字屬性:<GridName="grid1">…</grid>(3)為Window1類增加變量:doublex,y;boolmark=false;(4)在Window1類中增加MakeRectangle方法,參數(x1,y1)是鼠標左鍵單擊處點的位置,作為矩形的一個頂點,(x2,y2)是拖動鼠標移動到另一點的位置,返回一個數組,4個元素按順序分別是定義所畫橢圓或圓矩形的左上角x、y座標,矩形寬和高。方法如下:privatedouble[]MakeRectangle(doublex1,doubley1,doublex2,doubley2){doubletop,left,bottom,right;top=y1<=y2?y1:y2;left=x1<=x2?x1:x2; bottom=y1>y2?y1:y2; right=x1>x2?x1:x2;double[]xs={left,top,right-left,bottom-top};returnxs;}(5)為Window1事件MouseDown、MouseUp、MouseMove增加事件處理函數如下:privatevoidWindow_MouseDown(objectsender,MouseButtonEventArgse){if(e.LeftButton==MouseButtonState.Pressed){ellipse1.Visibility=Visibility.Visible;Pointposition=e.GetPosition(grid1);x=position.X;y=position.Y;ellipse1.Width=1; ellipse1.Height=1;ellipse1.Margin=newThickness(x,y,0,0);mark=true;}}privatevoidWindow_MouseMove(objectsender,MouseEventArgse){if(mark){Pointposition=e.GetPosition(grid1);doublepX=position.X;doublepY=position.Y;double[]xs=MakeRectangle(x,y,pX,pY);ellipse1.Width=xs[2];ellipse1.Height=xs[3];ellipse1.Margin=newThickness(xs[0],xs[1],0,0);}}privatevoidWindow_MouseUp(objectsender,MouseButtonEventArgse){mark=false;}(6)編譯運行,在Window1控件中拖動鼠標可以畫圓或橢圓。5.3.5控件Polyline和PolygonPolyline類的屬性Ponints是點結構數組,將數組元素Ponints[0]和Ponints[1]、Ponints[1]和Ponints[2]、…等點連接為多條線段。Polygon和Polyline類功能類似,但將最后一點和開始點連接為線段,由多條線段組成封閉圖形。實際上如設置類Polyline屬性IsClose=true,也能完成Polygon類相同功能。XAML標記例子:<PolylinePoints="10,11060,10110,110"Stroke="Black"StrokeThickness="4"/>【例5.7】在Windows畫圖程序中,可以拖動鼠標畫任意曲線。本例實現用拖動鼠標左鍵在主窗體中畫曲線。每條曲線都是由若干很短的線段組成。鼠標左鍵在按下狀態,移動鼠標,每次移動很短距離,畫出這段線段,所有這些線段組合起來,形成一條曲線。(1)創建WPF項目。在<grid>面板中增加Polyling控件XAML標記。<GridName="grid1"><PolylineStroke="Black"StrokeThickness="1"Name="polyline1/></Grid>(2)為Window1類增加如下變量:PointCollectionmyPoints=newPointCollection();boolmark=false;(3)為Window1控件增加事件處理函數:privatevoidWindow_MouseDown(objectsender,MouseButtonEventArgse){myPoints.Clear(); Pointp1=e.GetPosition(grid1);myPoints.Add(p1);mark=true;}privatevoidWindow_MouseMove(objectsender,MouseEventArgse){if(mark){Pointp1=e.GetPosition(grid1);myPoints.Add(p1);polyline1.Points=myPoints;}}privatevoidWindow_MouseUp(objectsender,MouseButtonEventArgse){mark=false; }(4)運行,在主窗體中拖動鼠標左鍵可以畫線。5.3.6控件Path使用Path控件可以畫任意曲線?!纠?.8】使用Path控件例子。在Grid標記中增加如下標記:<PathStroke="Black"StrokeThickness="1"Fill="#CCCCFF"><Path.Data> <GeometryGroupFillRule="EvenOdd"><LineGeometryStartPoint="10,10"EndPoint="50,30"/><EllipseGeometryCenter="40,70"RadiusX="30"RadiusY="30"/><RectangleGeometryRect="30,55,100,30"/></GeometryGroup></Path.Data></Path><PathStroke="Black"StrokeThickness="1"Margin="0,50,0,0"Data="M10,100C100,0200,200300,100"/>屬性Data也可采用路徑標記語法賦值,上例中第二個Path控件采用路徑標記語法生成貝塞爾曲線,依靠XMAL解析器內部類型轉換器自動將路徑標記轉換為Geometry對象。該標記中,逗號前后的兩個數值表示一個點,點與點之間用空格分開,字符M或m表示Path起點,L或l表示線段終點(起點是當前點),H或h后的一個數值(不是點)表示x坐標值,表示當前點到這個x坐標的水平線段,V或v后的一個數值表示y坐標值,表示當前點到這個y坐標的垂直線段,C或c表示三次貝塞爾曲線控制點,Q或q表示二次貝塞爾曲線控制點,T或t表示平滑貝塞爾曲線控制點,A或a表示橢圓弧指令,Z或z表示Path終點。5.4使用Drawing派生類5.4.1繪圖基本方法GeometryDrawing類用來繪制各種形狀圖形,其屬性Geometry用來描述圖形的形狀,屬性Brush用來指定填充封閉圖形的刷子,屬性Pen指定繪制輪廓的筆。該類必須放在承載容器才能顯示所繪制的圖形,承載容器必須是FrameworkElement類的派生類,例如窗口或其它內容控件,常用的用法是GeometryDrawing類對象放到DrawingImage控件中,作為Image控件的數據源?!纠?.9】本例繪制橢圓,將如下標記放到Grid標記中。這是Drawing類繪圖基本方法。

<Image><Image.Source><DrawingImage><DrawingImage.Drawing><GeometryDrawingBrush="Orange"><GeometryDrawing.Geometry><EllipseGeometryCenter="50,50"RadiusX="45"RadiusY="20"/></GeometryDrawing.Geometry><GeometryDrawing.Pen><PenThickness="5"Brush="Black"/></GeometryDrawing.Pen></GeometryDrawing></DrawingImage.Drawing></DrawingImage></Image.Source></Image>【例5.10】可以使用XAML標記或代碼繪制圖形。publicWindow1(){InitializeComponent();EllipseGeometryellipse2=newEllipseGeometry();ellipse2.RadiusX=45;ellipse2.RadiusY=20;ellipse2.Center=newPoint(50,50);GeometryDrawingaDrawing=newGeometryDrawing();aDrawing.Geometry=ellipse2;aDrawing.Brush=Brushes.Orange;aDrawing.Pen=newPen(Brushes.Black,10.0);DrawingImagedi=newDrawingImage(aDrawing);Gridgrid=newGrid(); Imageimage=newImage();grid.Children.Add(image);image.Source=di;this.Content=grid;}5.4.2Geometry類【例5.11】本例繪制圓角矩形,將如下XAML標記替換例5.9相應XAML標記。<GeometryDrawing.Geometry><RectangleGeometryRect="0,0,100,50"RadiusX="10"RadiusY="10"/></GeometryDrawing.Geometry>【例5.12】本例繪制一條線段,將如下XAML標記替換例5.9相應XAML標記。<GeometryDrawing.Geometry><LineGeometryStartPoint="10,20"EndPoint="100,130"/></GeometryDrawing.Geometry>【例5.13】本例使用PathGeometry類繪制兩條線段,將如下XAML標記替換例5.9相應XAML標記。<GeometryDrawing.Geometry><PathGeometry><PathFigure><LineSegmentPoint="0,100"/><LineSegmentPoint="100,100"/></PathFigure></PathGeometry></GeometryDrawing.Geometry>【例5.14】本例使用多條首尾連接線段類PolyLineSegment屬性Points路徑標記語法重做上例。用如下XAML標記替換上例兩條線段的XAML標記,顯示效果相同。<PolyLineSegmentPoints="0,100100,100"/>【例5.15】如果有兩組不連接或不是首尾連接的圖形,可以放到兩個PathFigure標記中。將如下XAML標記替換例5.9相應XAML標記。<GeometryDrawing.Geometry><PathGeometry><PathFigureIsClosed="True"><LineSegmentPoint="0,100"IsSmoothJoin="True"/><LineSegmentPoint="100,100"IsSmoothJoin="True"/></PathFigure>

<PathFigureIsClosed="True"StartPoint="100,0"><LineSegmentPoint="0,100"IsSmoothJoin="True"/><LineSegmentPoint="100,100"IsSmoothJoin="True"/></PathFigure> </PathGeometry><GeometryDrawing.Geometry>5.4.3GeometryGroup類如同時繪制多個RectangleGeometry、EllipseGeometry、LineGeometry或PathGeometry圖形,就必須將它們放到標記GeometryGroup中。在標記中,每個圖形都可以使用屬性Transform分別實現旋轉、縮放、扭曲和平移等變換?!纠?.16】用如下標記替換例5.9相應標記。<GeometryDrawing.Geometry><GeometryGroup><EllipseGeometryCenter="50,50"RadiusX="45"RadiusY="20"/><EllipseGeometryCenter="50,50"RadiusX="20"RadiusY="45"/></GeometryGroup></GeometryDrawing.Geometry>

5.4.4CombinedGeometry類區域是封閉曲線所圍內部平面部分。區域可以是簡單的(如單個矩形內部)或復雜的(如多邊形或閉合曲線的組合)。圖5.6中的左邊第1圖顯示了兩個區域相交,一個矩形和一個用曲線畫出的封閉圖形??梢酝ㄟ^合并現有兩個區域來創建復雜區域。兩個區域的交集(Intersect)是同時屬于兩個區域的所有點的集合,并集(Union)是多個區域的所有點的集合,兩個區域并集減去這兩者的交集,即圖5.6中的左數第4圖顯示的黑色區域,稱作異或(Xor)??蓮木匦螀^域除去和另一個區域的交集,如圖5.6中右數第1圖區域,稱作Exclude?!纠?.17】用如下XAML標記替換例5.9相應XAML標記,從Geometry1標記內的橢圓除去和Geometry2標記內的橢圓相交部分。<GeometryDrawing.Geometry><CombinedGeometryGeometryCombineMode="Exclude"><CombinedGeometry.Geometry1><EllipseGeometryCenter="50,50"RadiusX="45"RadiusY="20"/></CombinedGeometry.Geometry1><CombinedGeometry.Geometry2><EllipseGeometryCenter="50,50"RadiusX="20"RadiusY="45"/></CombinedGeometry.Geometry2></CombinedGeometry></GeometryDrawing.Geometry>5.5使用Visual類派生類Visual類是一個抽象類,其派生類DrawingVisual是一個輕量繪圖類,用于呈現形狀、圖像或文本,它不提供布局、輸入、焦點或事件處理功能,從而能夠改善其性能。必須將DrawingVisual對象放到一個派生自FrameworkElement類的宿主容器,例如窗體、Image類對象、Panel類對象等。類DrawingVisual對XAML支持很少,大部分圖形要用代碼實現。5.5.1繪圖基本方法【例5.18】使用DrawingVisual繪制一個橢圓和矩形。其代碼如下:publicpartialclassWindow1:Window{privateVisualCollection_children;DrawingVisualdv=newDrawingVisual();publicWindow1(){_children=newVisualCollection(this); InitializeComponent();_children.Add(dv);using(DrawingContextdc=dv.RenderOpen()){Rectrect=newRect(newPoint(100,100),newSize(100,50));

dc.DrawRectangle(Brushes.Blue,(Pen)null,rect);dc.DrawEllipse(Brushes.Red,(Pen)null,newPoint(100,50),100,50);}} protectedoverrideintVisualChildrenCount{get{return_children.Count;}}protectedoverrideVisualGetVisualChild(intindex){if(index<0||index>_children.Count){thrownewArgumentOutOfRangeException();}return_children[index];}}5.5.2DrawingContext類方法【例5.19】本例用DrawDrawing方法繪制使用GeometryDrawing方法生成的圖形。用如下語句替換例5.18的Using語句中代碼。EllipseGeometryellipse2=newEllipseGeometry(); ellipse2.RadiusX=45; ellipse2.RadiusY=20; ellipse2.Center=newPoint(50,50);GeometryDrawingaDrawing=newGeometryDrawing(); aDrawing.Geometry=ellipse2;aDrawing.Brush=Brushes.Orange; dc.DrawDrawing(aDrawing);【例5.20】本例介紹DrawGeometry方法用法。用如下語句替換例5.18的Using語句中代碼。dc.DrawGeometry(Brushes.Red,(Pen)null,Geometry.Parse(@"M0,00,100100,100Z"));5.6Pen類和Brush類5.6.1Pen類Pen類包括如下屬性:Thickness和Brush:筆的粗細和筆使用的刷子。DashStyle:默認值為實線,也可為虛線或點劃線,其子屬性Dashes是一個數組,表示虛線或點劃線樣式,例如Dashes="a,b"中的a和b是數字,a表示是一個寬為Thickness(筆的粗細),長為(a+1)*Thickness的線,其后為空格,按照此規律重復,重復周期長度為(a+b)*Thickness。因此Dashes="0,1"表示實線。如果Dashes="a1,b1,a2,b2",則(a1,b1)和(a2,b2)意義同前,重復周期長度為(a1+b1+a2+b2)*Thickness。數組可以有多項,但必須為偶數項。【例5.21】為字符增加虛下劃線的XAML標記如下,注意省略了一些標記。<TextBlockFontSize="36">帶下劃線字符

<TextBlock.TextDecorations><TextDecorationLocation="Underline"PenThicknessUnit="FontRecommended"><TextDecoration.Pen><PenThickness="3"Brush="Red"><Pen.DashStyle>

<DashStyleDashes="1,4"/></Pen.DashStyle></Pen>

</TextDecoration.Pen></TextDecoration></TextBlock.TextDecorations></TextBlock>DashCap、EndLineCap和StartLineCap:前兩個屬性是曲線末端的形狀,第3個屬性是曲線開始的形狀,可以是枚舉類型PenLineCap的值:Flat(一個未超出直線上最后一點的線帽,等同于無線帽)、Square(一個高度等于直線粗細、長度等于直線粗細一半的矩形)、Round一個直徑等于直線粗細的半圓形)、Triangle(一個底邊長度等于直線粗細的等腰直角三角形)。LineJoin:兩條線段連接處的形狀??梢允敲杜e類型PenLineJoin的值:Miter(常規角頂點)、Bevel(斜角頂點)、Round(圓角頂點)?!纠?.22】本例顯示Pen類屬性LineJoin、EndLineCap和StartLineCap的具體形狀。將如下XAML標記增加到Grid記中,運行效果見圖。5.6.2SolidColorBrush畫刷又稱作單色畫刷,使用單一顏色填充封閉區域。一般控件屬性Background,Shape類屬性Fill,GeometryDrawing類屬性Brush是一個畫刷,如果令其為單一顏色值,實際上設置該屬性為SolidColorBrush單色畫刷類對象,例如:<GeometryDrawingBrush=“Orange”/>。單色畫刷類SolidColorBrush最常用的屬性Color,表示畫刷的顏色。【例5.23】使用SolidColorBrush單色畫刷例子。將XAML標記放到Grid標記中。<RectangleWidth="75"Height="75"><Rectangle.Fill><SolidColorBrushColor="Red"/> <!--也可為其它畫刷--></Rectangle.Fill></Rectangle>又稱作顏色線形漸變畫刷。其常用屬性如下:StartPoint和EndPoint:Point結構對象,顏色將沿著兩點連線漸變。GradientStops:GradientStop類對象的集合。GradientStop類表示漸變的位置和顏色。位置是StartPoint和EndPoint兩點連線用分數表示的相對值,例如,0.5表示連線中間位置。例如下例中,從連線開始(0.0)到四分之一處(0.25),從黃色漸變到紅色,從四分之一處到連線終點,從紅色漸變到藍色。5.6.3LinearGradientBrush畫刷【例5.24】本例繪制用顏色線形漸變畫刷填充的矩形。將以下標記放到Grid標記中。<RectangleWidth="200"Height="100"><Rectangle.Fill><LinearGradientBrushStartPoint="0,0"EndPoint="1,1"><GradientStopColor="Yellow"Offset="0.0"/><GradientStopColor="Red"Offset="0.25"/><GradientStopColor="Blue"Offset="1.0"/></LinearGradientBrush></Rectangle.Fill></Rectangle>【例5.25】本例用代碼實現上例相同功能。RectanglediagonalFillRectangle=newRectangle();diagonalFillRectangle.Width=200;diagonalFillRectangle.Height=100;LinearGradientBrushmyLinearGradientBrush=newLinearGradientBrush();myLinearGradientBrush.StartPoint=newPoint(0,0);myLinearGradientBrush.EndPoint=newPoint(1,1);myLinearGradientBrush.GradientStops.Add(newGradientStop(Colors.Yellow,0.0));myLinearGradientBrush.GradientStops.Add(newGradientStop(Colors.Red,0.25));myLinearGradientBrush.GradientStops.Add(newGradientStop(Colors.Blue,1.0));diagonalFillRectangle.Fill=myLinearGradientBrush;Content=diagonalFillRectangle;5.6.4RadialGradientBrush畫刷又稱作顏色徑向漸變畫刷。其常用屬性如下:Center、RadiusX和RadiusY:定義一個矩形,顏色沿該矩形的內切橢圓或圓徑向漸變。三個屬性意義分別是內切橢圓或圓的圓心、水平半徑和垂直半徑。GradientOrigin:顏色漸變開始的點。GradientStops:意義和LinearGradientBrush同名屬性類似。【例5.26】本例繪制用顏色徑向漸變畫刷填充的矩形。將以下標記放到Grid標記中。<RectangleWidth="200"Height="100"><Rectangle.Fill><RadialGradientBrushGradientOrigin="0.4,0.4"Center="0.5,0.5"RadiusX="0.5"RadiusY="0.5"><RadialGradientBrush.GradientStops><GradientStopColor="Yellow"Offset="0"/><GradientStopColor="Red"Offset="0.25"/><GradientStopColor="Blue"Offset="0.75"/><GradientStopColor="LimeGreen"Offset="1"/></RadialGradientBrush.GradientStops></RadialGradientBrush></Rectangle.Fill></Rectangle>5.6.5ImageBrush畫刷【例5.27】本例在窗體中顯示一幅圖像。Stretch屬性參見5.6.6節。<CanvasMargin="12,31"> <Canvas.Background><ImageBrushImageSource="../../p.bmp"Stretch="None"/></Canvas.Background></Canvas>【例5.28】本例用代碼在矩形中顯示一幅圖像。在構造函數中增加如下語句。RectangleexampleRectangle=newRectangle();exampleRectangle.Width=75;exampleRectangle.Height=75;ImageBrushmyBrush=newImageBrush();myBrush.ImageSource=newBitmapImage(newUri(@"..\..\p.bmp",UriKind.Relative));exampleRectangle.Fill=myBrush;Content=exampleRectangle;5.6.6TileBrush類TileBrush類是ImageBrush、DrawingBrush和VisualBrush基類,其常用屬性如下:Stretch:該屬性是Stretch枚舉類型,可以取值為:None、Fill、Uniform、UniformToFill。Viewport和ViewportUnits:默認情況下TileBrush畫刷完全填充被填充對象,也可僅填充一部分。Viewport決定填充大小和位置,ViewportUnits決定了Viewport是使用絕對坐標還是相對坐標指定的。TileMode:設置該屬性可使畫刷以基本圖塊為基礎,形成多個基本圖塊,按照一定規律排列。該屬性為TileMode枚舉類型值,可取值為:None、Tile、FlipX、FlipY、FlipXY?!纠?.29】本例將在矩形中顯示4個基本圖塊。<RectangleWidth="100"Height="100"><Rectangle.Fill><ImageBrushImageSource="..\..\p.bmp"Viewport="0,0,0.5,0.5"TileMode="Tile"/></Rectangle.Fill></Rectangle>5.6.7DrawingBrush畫刷【例5.30】本例在窗體中顯示一幅圖像。注意基本塊為被填充矩形左上角第一行的一黑、一白,第二行的一白、一灰4個小矩形,在X和Y方向各重復4次。<RectangleWidth="200"Height="200"><Rectangle.Fill><DrawingBrushViewport="0,0,0.25,0.25"TileMode="Tile"><DrawingBrush.Drawing><GeometryDrawing><GeometryDrawing.Geometry><GeometryGroup><RectangleGeometryRect="0,0,50,50"/><RectangleGeometryRect="50,50,50,50"/></GeometryGroup></GeometryDrawing.Geometry>

<GeometryDrawing.Brush><LinearGradientBrush><GradientStopOffset="0.0"Color="Black"/><GradientStopOffset="1.0"Color="Gray"/></LinearGradientBrush></GeometryDrawing.Brush></GeometryDrawing></DrawingBrush.Drawing></DrawingBrush></Rectangle.Fill> </Rectangle>5.6.8VisualBrush畫刷【例5.31】本例在窗體中顯示4個按鈕。屬性TileMode、Viewport參見5.6.6節。<Window…><!--注意省略一些標記,實際程序必須加上--> <Window.Background><VisualBrushTileMode="FlipXY"Viewport="0,0,0.5,0.5">

<VisualBrush.Visual><Button>OK</Button></VisualBrush.Visual>

</VisualBrush></Window.Background></Window> 5.7圖形變換5.7.1Transform派生類Transform類是實現二維變換功能的一些類的基類,其派生類包括RotateTransform(旋轉)、ScaleTransform(縮放)、SkewTransform(扭曲)和TranslateTransform(平移)。RotateTransform類:其常用屬性包括Angle、CenterX和CenterY,該類使圖形圍繞點(CenterX,CenterY)旋轉指定的Angle角度。參見例5.2。ScaleTransform類:其屬性CenterX、CenterY指定縮放操作的中心點,屬性ScaleX和ScaleY指定圖形放大倍數。【例5.32】本例定義了兩個矩形,然后寬和高分別放大2倍,但屬性CenterX、CenterY不同,注意兩者的不同,圖5.14中小矩形為初始位置,具體XAML標記如下:<GridHeight="162"><RectangleHeight="50"Width="50"Fill="LightBlue"Margin="12,45,0,0"HorizontalAlignment="Left"VerticalAlignment="Top"><Rectangle.RenderTransform><ScaleTransformCenterX="0"CenterY="0"ScaleX="2"ScaleY="2"/></Rectangle.RenderTransform></Rectangle>

<RectangleWidth="50"Height="50"Fill="LightGreen"Margin="0,45,54,0"HorizontalAlignment="Right"VerticalAlignment="Top"><Rectangle.RenderTransform><ScaleTransformCenterX="25"CenterY="25"ScaleX="2"ScaleY="2"/></Rectangle.RenderTransform></Rectangle></Grid>SkewTransform類:該類可用于對圖像進行扭曲,其屬性CenterX和CenterY指定扭曲的中心點,屬性AngleX和AngleY指定沿x軸和y軸的扭曲角度。【例5.33】本例將矩形沿X軸扭曲45度,XAML標記如下:<RectangleFill="LightBlue"Margin="100,100,100,100"><Rectangle.RenderTransform><SkewTransformCenterX="0"CenterY="0"AngleX="45"AngleY="0"/></Rectangle.RenderTransform></Rectangle>TranslateTransform類:該類平移圖像,屬性X和Y是沿X軸和Y軸方向距離。5.7.2TransformGroup類

如果要對一個圖形完成多個變換,要將多個變換放到TransformGroup標記中?!纠?.34】本例將一個按鈕沿Y軸方向放大3倍后,旋轉45度,XAML標記如下:<ButtonRenderTransformOrigin="0.5,0.5"Margin="100,100,100,100">Click<Button.RenderTransform><TransformGroup><ScaleTransformScaleY="3"/><RotateTransformAngle="45"/></TransformGroup></Button.RenderTransform></Button>5.7.3Matrix結構可以使用矩陣記錄所使用的變換。m×n矩陣是以m行和n列排列的一組數字,例如一個3×3矩陣記如圖5.15。兩個行、列相同的矩陣可以相加,例如:[a33]+[b33]=[c33],矩陣相加運算的規則是:cij=aij+bij,i和j為常量,即相對應位置的項相加。如果有矩陣[amn]和[bnk],[amn]矩陣的列數等于[bnk]矩陣的行數,兩個矩陣可以相乘,記為:[amn]*[bnk]=[cmk],矩陣相乘的運算的規則是:cij=∑(ait*btj),其中,i和j為常量,t為變量,初始值為1,最大值為n。如果將平面中的點視為1×2矩陣,則可通過將該點乘以2×2變換矩陣來變形該點。圖5.16圖是點(2,1)在X軸按比例3放大,Y軸不變,變換結果如圖5.17。圖5.18表示點(2,1)旋轉了90度。圖5.19表示點(2,1)以x軸為對稱軸的新點。假定要從點(2,1)開始,將其旋轉90度,在x方向將其平移3個單位,在y方向將其平移4個單位??赏ㄟ^先使用矩陣乘法再使用矩陣加法來完成此操作

圖5.15矩陣 圖5.16矩陣相乘 圖5.17比例放大

圖5.18點的旋轉

圖5.19點的對稱變換

圖5.20點的復合變換

圖5.21用仿射矩陣表示的復合變換 圖5.22仿射矩陣

如果用矩陣[211]代表點(2,1),用3×3變換矩陣記錄兩個變換,可用一個矩陣乘法代替以上的兩個矩陣運算,見圖5.21。注意運算結果的矩陣[261]代表點(2,6),即點(2,1)映射到了點(2,6)。這個3×3矩陣叫作仿射矩陣,它和前邊的兩個2×2矩陣的關系如圖5.22,其中第三列固定為0、0、1。WPF使用System.Windows.Media.Matrix結構封裝表示3行3列仿射矩陣,用來記錄圖形的復雜變換。Matrix結構用屬性M11、M12、M21、M22、OffsetX和OffsetY表示3×3變換矩陣的各個項,其結構構造函數如下:publicMatrix(doublem11,doublem12,doublem21,doublem22,doubleoffsetX,doubleoffsetY)Matrix常用方法和屬性如下:靜態屬性publicstaticMatrixIdentity{get;}:得到單位矩陣。方法Rotate(doubleangle):使矩陣增加相對于原點順時針旋轉angle角度變換。方法RotateAt(doubleangle,doublecenterX,doublecenterY):使矩陣增加相對于點(centerX,centerY)順時針旋轉angle角度變換。方法Scale(doublescaleX,doublescaleY):使矩陣增加在X軸和Y軸方向對圖形放大或縮小的變換。參數1指定在X軸方向縮放的值,參數2指定在Y軸方向縮放的值。方法Translate(doubleoffsetX,doubleoffsetY):使矩陣增加在(在)X軸和Y軸方向移動的變換。參數1指定在X軸方向移動的值,參數2指定在Y軸方向移動的值。方法PointTransform(Pointpoint):對point點進行變換,參數也可為點數組5.7.4MatrixTransform類【例5.35】本例說明MatrixTransform.類使用方法,如下XAML標記。<ButtonMinWidth="100"Height="38"Width="100">Click<Button.RenderTransform><MatrixTransformx:Name="myMatrixTransform"><MatrixTransform.Matrix><MatrixOffsetX="10"OffsetY="10"M11="1.5"M12="1"/></MatrixTransform.Matrix></MatrixTransform></Button.RenderTransform></Button>然后在構造函數最后增加如下語句:Matrixm=myMatrixTransform.Matrix;m.Translate(-100,-100);myMatrixTransform.Matrix=m;5.7.5控件的變換所有控件都可以使用Transform派生類完成變換,例5.36是對控件Button進行變換。所有控件都有屬性LayoutTransform和RenderTransform,前者是在布局之前對控件進行變換,而后者則是在布局之后對控件進行變換在窗體顯示?!纠?.36】本例使用LayoutTransform將Button2旋轉30度,運行效果見圖5.25。如果修改Button.LayoutTransform為Button.RenderTransform,運行效果如圖5.26。<Window…Height="175"Width="162"><!--一些標記未給出--><StackPanelWidth="137"Height="140"><ButtonHeight="30"Name="button1"Width="100">Button1</Button><ButtonHeight="30"Name="button2"Width="100">Button2<Button.LayoutTransform><RotateTransformAngle="30"CenterX="50"/></Button.LayoutTransform></Button><ButtonHeight="30"Name="button3"Width="100">Button3</Button></StackPanel></Window>5.7.6Drawing類圖形變換Geometry派生類RectangleG

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論