在软件行业,经常会听到一句话“文不如表,表不如图”说明了图形在软件应用中的重要性。同样在WPF开发中,为了程序美观或者业务需要,经常会用到各种个样的图形。今天以一些简单的小例子,简述WPF开发中几何图形(Geometry)相关内容,仅供学习分享使用,如有不足之处,还请指正。
几何图形可以随意和进行缩放而不变形,这是和位图最大的差异。Geometry类及其派生类(PathGeometry,EllipseGeometry,CombinedGeometry)可以用于描述2D形状的几何图形。Geometry对象可以是矩形和椭圆形等简单图形,也可以是由两个或者多个几何对象创建的复合图形,如:PathGeometry和StreamGeometry等,可以用于绘制曲线或其他复杂图形。
Geometry类继承自Freezable类,因此可以声明为资源,对象之间共享,变为只读提高性能,或者克隆及线程安全等。具体可了解Freezable相关知识。
上一篇文章了解了Shape类也是在页面绘制图形,那Shape和Geometry有什么区别和联系呢?
首先Geometry和Shape类都是用于描述2D形状(如:EllipseGeometry和Ellipse),但它们之间存在一些重要的区别。具体如下:
Geometry是abstract修饰的抽象类,所以只能使用其派生类进行绘制几何图形,而Geometry的派生类可以分为三个类别:简单几何,路径几何,复合几何。
简单几何图形,WPF系统自带了几个默认的几何图形,如LineGeometry,RectangleGeometry,和 EllipseGeometry,用于创建基本的几何图形,如:线条,矩形,椭圆等。
虽然PathGeometry也能实现基本的几何图形,但是用WPF默认提供的类,则更简单,也方便理解。
由于Geometry不是UI元素,不能独立进行自我绘制并呈现 ,所以使用Path形状来呈现。LineGeometry通过设置起始点坐标(StartPoint)和结束坐标(EndPoint)来定义直线。
如下所示:
<Path Stroke="Black" StrokeThickness="1" >
<Path.Data>
<LineGeometry StartPoint="10,20" EndPoint="100,130" />
</Path.Data>
</Path>
上述代码通过C#代码实现,如下所示:
LineGeometry lineGeometry = new LineGeometry();
lineGeometry.StartPoint = new Point(10, 20);
lineGeometry.EndPoint = new Point(100, 130);
Path path = new Path();
path.Stroke = Brushes.Black;
path.StrokeThickness = 1;
path.Data = lineGeometry;
通过LineGeometry实现直线,效果如下所示:
EllipseGeometry通过设置中心点的坐标(Center)和x半径(RadiusX),y轴半径(RadiusY)来绘制椭圆。
绘制一个坐标相等的圆,如下所示:
<Path Fill="Gold" Stroke="Black" StrokeThickness="1">
<Path.Data>
<EllipseGeometry Center="50,50" RadiusX="50" RadiusY="50" />
</Path.Data>
</Path>
上述代码通过C#代码实现,如下所示:
EllipseGeometry ellipseGeometry = new EllipseGeometry();
ellipseGeometry.Center = new Point(50, 50);
ellipseGeometry.RadiusX = 50;
ellipseGeometry.RadiusY = 50;
Path path = new Path();
path.Fill = Brushes.Gold;
path.Stroke = Brushes.Black;
path.StrokeThickness = 1;
path.Data = ellipseGeometry;
通过EllipseGeometry绘制圆,示例如下所示:
RectangleGeometry通会Rect结构来描述矩形,分别是起始坐标和宽度,高度来定义矩形,如下所示:
<Path Fill="LemonChiffon" Stroke="Black" StrokeThickness="1">
<Path.Data>
<RectangleGeometry Rect="50,50,100,60" />
</Path.Data>
</Path>
上述代码用C#实现,如下所示:
RectangleGeometry rectangleGeometry = new RectangleGeometry();
rectangleGeometry.Rect = new Rect(50, 50, 100, 60);
Path path = new Path();
path.Fill = Brushes.LemonChiffon;
path.Stroke = Brushes.Black;
path.StrokeThickness = 1;
path.Data = rectangleGeometry;
通过RectangleGeometry绘制矩形,示例如下所示:
通过将Geometry应用到Image的Clip属性,可以实现图像的裁剪功能,如下所示:
<StackPanel Orientation="Vertical" Margin="10">
<TextBlock Text="原图"></TextBlock>
<Image Source="imgs\bingdundun.jpeg" Width="300" Height="200" HorizontalAlignment="Left">
</Image>
<TextBlock Text="裁剪后"></TextBlock>
<Image Source="imgs\bingdundun.jpeg" Width="300" Height="200" HorizontalAlignment="Left">
<Image.Clip>
<EllipseGeometry RadiusX="130" RadiusY="80" Center="150,100"/>
</Image.Clip>
</Image>
</StackPanel>
上述代码用C#实现如下所示:
Image image = new Image();
Uri imageUri = new Uri(@"imgs\bingdundun.jpeg", UriKind.RelativeOrAbsolute);
image.Source = new BitmapImage(imageUri);
image.Width = 300;
image.Height = 200;
image.HorizontalAlignment = HorizontalAlignment.Left;
// 用椭圆定义裁剪区域.
EllipseGeometry ellipseGeometry = new EllipseGeometry();
ellipseGeometry.Center = new Point(150, 10);
ellipseGeometry.RadiusX = 130;
ellipseGeometry.RadiusY = 80;
image.Clip = ellipseGeometry;
通过Geometry实现图像裁剪,示例如下所示:
PathGeometry类及其轻型等效项(StreamGeometry类)主要用于描述弧线,曲线,直线组成的多个复杂图形的方法。PathGeometry的核心是PathFigure对你的集合。每一个PathFigure本身由一个或多个PathSegment对象组成,每一个PathSegment描述图形的一个小部分。常见的PathSegment主要有以下几种:
关于PathFigure有以下几点说明:
关于PathGeometry的示例代码如下所示:
<Path Stroke="Black" StrokeThickness="1" >
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigure StartPoint="10,50">
<PathFigure.Segments>
<BezierSegment Point1="100,0" Point2="200,200" Point3="300,100"/>
<LineSegment Point="400,100" />
<ArcSegment Size="50,50" RotationAngle="45" IsLargeArc="True" SweepDirection="Clockwise" Point="200,100"/>
</PathFigure.Segments>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
上述XAML代码用C#实现,如下所示:
PathFigure pathFigure = new PathFigure();
pathFigure.StartPoint = new Point(10, 50);
pathFigure.Segments.Add(
new BezierSegment(
new Point(100, 0),
new Point(200, 200),
new Point(300, 100),
true /* IsStroked */ ));
pathFigure.Segments.Add(
new LineSegment(
new Point(400, 100),
true /* IsStroked */ ));
pathFigure.Segments.Add(
new ArcSegment(
new Point(200, 100),
new Size(50, 50),
45,
true, /* IsLargeArc */
SweepDirection.Clockwise,
true /* IsStroked */ ));
/// Create a PathGeometry to contain the figure.
PathGeometry pathGeometry = new PathGeometry();
pathGeometry.Figures.Add(pathFigure);
// Display the PathGeometry.
Path path = new Path();
path.Stroke = Brushes.Black;
path.StrokeThickness = 1;
path.Data = pathGeometry;
上述代码创建的形状如下所示:
与 PathGeometry 类一样,StreamGeometry 定义可能包含曲线、弧线和直线的复杂几何形状。与 PathGeometry 不同,StreamGeometry 的内容不支持数据绑定、动画或修改。当需要描述复杂几何图形,但又不希望产生支持数据绑定、动画或修改的开销时,请使用 StreamGeometry。由于 StreamGeometry 类的高效性,该类是描述装饰器的不错选择。
使用 GeometryGroup、CombinedGeometry 或通过调用静态 Geometry 方法 Combine,可以创建复合几何对象。两者之间的差异如下:
简单点来说:GeometryGroup是进行对象的合并,CombinedGeometry是进行合并对象的布尔运算。
下面示例CombinedGeometry的“并集”,如下所示:
<Path Stroke="Black" StrokeThickness="1" Fill="#CCCCFF">
<Path.Data>
<CombinedGeometry GeometryCombineMode="Union">
<CombinedGeometry.Geometry1>
<EllipseGeometry RadiusX="50" RadiusY="50" Center="75,75" />
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<EllipseGeometry RadiusX="50" RadiusY="50" Center="125,75" />
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Path.Data>
</Path>
CombinedGeometry并集示例如下所示:
参考文档:
https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/graphics-multimedia/geometry-overview?view=netframeworkdesktop-4.8
以上就是【不可不知的WPF几何图形(Geometry)】的全部内容,关于更多详细内容,可参考官方文档。希望能够一起学习,共同进步。