在 SkiaSharp 中绘制简单圆圈
了解 SkiaSharp 绘图的基础知识,包括画布和油漆对象
本文介绍使用 SkiaSharp 在 Xamarin.Forms 中绘制图形的概念,包括创建 SKCanvasView
对象来托管图形、处理 PaintSurface
事件,以及使用 SKPaint
对象指定颜色和其他绘图属性。
示例程序包含本系列 SkiaSharp 文章的所有示例代码。 第一页的名称为 Simple Circle,其中调用页面类 SimpleCirclePage
。 此代码演示如何在页面中心绘制一个圆圈,半径为 100 像素。 圆的轮廓为红色,圆的内部为蓝色。
SimpleCircle
页类派生自 ContentPage
,并包含 SkiaSharp 命名空间的两个 using
指令:
using SkiaSharp;
using SkiaSharp.Views.Forms;
类的以下构造函数创建一个 SKCanvasView
对象,附加 PaintSurface
事件的处理程序,并将 SKCanvasView
对象设置为页面的内容:
public SimpleCirclePage()
{
Title = "Simple Circle";
SKCanvasView canvasView = new SKCanvasView();
canvasView.PaintSurface += OnCanvasViewPaintSurface;
Content = canvasView;
}
SKCanvasView
占据页面的整个内容区域。 也可以将 SKCanvasView
与其他 Xamarin.FormsView
衍生工具组合在一起,如其他示例所示。
PaintSurface
事件处理程序是执行所有绘图的位置。 在程序运行时,可以多次调用此方法,因此它应保留重新创建图形显示所需的所有信息:
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
...
}
事件附带的 SKPaintSurfaceEventArgs
对象有两个属性:
SKImageInfo
类型的Info
SKSurface
类型的Surface
SKImageInfo
结构包含有关绘图图面的信息,最重要的是其宽度和高度(以像素为单位)。 SKSurface
对象表示绘图图面本身。 在此程序中,绘图图面是视频显示,但在其他程序中,SKSurface
对象还可以表示使用 SkiaSharp 绘制的位图。
SKSurface
最重要的属性是 SKCanvas
类型的 Canvas
。 此类是用于执行实际绘图的图形绘图上下文。 SKCanvas
对象封装图形状态,其中包括图形转换和剪辑。
下面是 PaintSurface
事件处理程序的典型开始:
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
...
}
Clear
方法使用透明颜色清除画布。 重载允许你为画布指定背景色。
这里的目标是绘制一个充满蓝色的红色圆圈。 由于此特定图形图像包含两种不同的颜色,因此需要在两个步骤中完成该作业。 第一步是绘制圆的轮廓。 若要指定线条的颜色和其他特征,请创建并初始化 SKPaint
对象:
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
...
SKPaint paint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = Colors.Red.ToSKColor(),
StrokeWidth = 25
};
...
}
Style
属性表示你想描边一条线(在本例中为圆的轮廓),而不是填充内部。 SKPaintStyle
枚举的三个成员如下所示:
默认为 Fill
。 使用第三个选项可以划线并用相同颜色填充内部。
将 Color
属性设置为类型为 SKColor
的值。 获取 SKColor
值的一种方法是使用扩展方法 ToSKColor
将 Xamarin.FormsColor
值转换为 SKColor
值。 SkiaSharp.Views.Forms
命名空间中的 Extensions
类包括其他方法,这些方法在 Xamarin.Forms 值和 SkiaSharp 值之间进行转换。
StrokeWidth
属性指示线条的粗细。 此处,它设置为 25 像素。
使用该 SKPaint
对象绘制圆圈:
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
...
canvas.DrawCircle(info.Width / 2, info.Height / 2, 100, paint);
...
}
相对于显示图面左上角指定坐标。 X 坐标向右增加,Y 坐标将向下增加。 在讨论图形时,通常使用数学表示法 (x, y) 来表示点。 点 (0, 0) 是显示图面的左上角,通常称为原点。
DrawCircle
的前两个参数指示圆中心的 X 和 Y 坐标。 这些值分配给显示图面的宽度和高度的一半,以将圆的中心置于显示图面的中心。 第三个参数指定圆的半径,最后一个参数是 SKPaint
对象。
若要填充圆圈的内部,可以更改 SKPaint
对象的两个属性,然后再次调用 DrawCircle
。 此代码还显示了从 SKColors
结构的许多字段之一获取 SKColor
值的替代方法:
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
...
paint.Style = SKPaintStyle.Fill;
paint.Color = SKColors.Blue;
canvas.DrawCircle(args.Info.Width / 2, args.Info.Height / 2, 100, paint);
}
这一次,DrawCircle
调用使用 SKPaint
对象的新属性填充圆圈。
下面是在 iOS 和 Android 上运行的程序:
自行运行程序时,可以侧转手机或模拟器,查看图形的重绘方式。 每次重新绘制图形时,都会再次调用 PaintSurface
事件处理程序。
还可以使用渐变或位图图块为图形对象着色。 “SkiaSharp 着色器”部分中将讨论这些选项。
SKPaint
对象不仅仅是图形绘图属性的集合。 这些对象是轻量级的。 可以像此程序一样重复使用 SKPaint
对象,也可以为绘图属性的各种组合创建多个 SKPaint
对象。 可以在 PaintSurface
事件处理程序之外创建和初始化这些对象,并且可以将它们另存为页面类中的字段。
注意
SKPaint
类定义一个 IsAntialias
,以便在图形呈现中启用抗锯齿。 反锯齿通常会导致视觉上更平滑的边缘,因此你可能希望针对大部分 SKPaint
对象将此属性设置为 true
。 为简单起见,此属性大多数示例页面中未设置。
虽然圆轮廓的宽度被指定为圆的半径的 25 像素 — 或四分之 — 一,但它看起来更薄,但有一个充分的理由:线条宽度的一半被蓝色圆遮盖。 DrawCircle
方法的参数定义圆的抽象几何坐标。 蓝色内部的大小设置为最接近的像素,但 25 像素宽的轮廓将几何圆 — 的一半跨越在内部和外部的一半。
与 Xamarin.Forms 集成文章中的下一个示例直观地演示了这一点。