绘制图形对象

浏览示例。 浏览示例

使用命名空间中的 Microsoft.Maui.Graphics .NET 多平台应用 UI (.NET MAUI) 图形,可以在定义为 ICanvas 对象的画布上绘制图形对象。

.NET MAUI GraphicsView 控件提供对 ICanvas 对象的访问,可对其设置属性以及调用以绘制图形对象的方法。 有关详细信息 GraphicsView,请参阅 GraphicsView

重要

图形对象以 ICanvas 像素为单位绘制。

绘制直线

可以使用该方法绘制ICanvasDrawLine线条,该方法需要四float个参数来表示线条的起点和终点。

以下示例演示如何绘制线条:

canvas.StrokeColor = Colors.Red;
canvas.StrokeSize = 6;
canvas.DrawLine(10, 10, 90, 100);

在此示例中,从 (10,10) 绘制红色对角线, (90,100) :

红线的屏幕截图。

注意

还有一个重载,它采用两PointFDrawLine参数。

以下示例演示如何绘制虚线:

canvas.StrokeColor = Colors.Red;
canvas.StrokeSize = 4;
canvas.StrokeDashPattern = new float[] { 2, 2 };
canvas.DrawLine(10, 10, 90, 100);

在此示例中,从 (10,10) 绘制到 (90,100) 的红色虚线:

虚线的屏幕截图。

有关虚线的详细信息,请参阅 绘制虚线对象

绘制椭圆形

可以使用方法绘制ICanvasDrawEllipse椭圆和圆圈,该方法需要yx类型、参数widthheight参数float

以下示例演示如何绘制椭圆:

canvas.StrokeColor = Colors.Red;
canvas.StrokeSize = 4;
canvas.DrawEllipse(10, 10, 100, 50);

在此示例中,绘制尺寸为 150x50 的红色椭圆, (10,10) :

红色椭圆的屏幕截图。

若要绘制圆圈,请使 width 方法的和 height 参数 DrawEllipse 相等:

canvas.StrokeColor = Colors.Red;
canvas.StrokeSize = 4;
canvas.DrawEllipse(10, 10, 100, 100);

在此示例中,在 (10,10,10) 绘制尺寸为 150x150 的红色圆圈:

红色圆圈的屏幕截图。

注意

也可以使用该方法绘制 DrawCircle 圆圈。

有关绘制虚线椭圆的信息,请参阅 绘制虚线对象

A filled ellipse can be drawn with the FillEllipse method, which also requires x, y, width, and height arguments, of type float:

canvas.FillColor = Colors.Red;
canvas.FillEllipse(10, 10, 150, 50);

在此示例中,绘制尺寸为 150x50 的红色填充椭圆, (10,10) :

红色填充椭圆的屏幕截图。

FillColor调用FillEllipse方法之前,必须将对象的属性ICanvas设置为 aColor

也可以使用该方法绘制 FillCircle 填充圆圈。

注意

DrawEllipse采用和FillEllipseRectF参数的重载Rect。 此外,还有 DrawCircleFillCircle 载。

绘制矩形

可以使用方法绘制ICanvasDrawRectangle矩形和正方形,该方法需要widthyx类型、参数和height参数float

以下示例演示如何绘制矩形:

canvas.StrokeColor = Colors.DarkBlue;
canvas.StrokeSize = 4;
canvas.DrawRectangle(10, 10, 100, 50);

在此示例中,绘制尺寸为 100x50 的深蓝色矩形, (10,10) :

深蓝色矩形的屏幕截图。

若要绘制正方形,请使 width 方法的和 height 参数 DrawRectangle 相等:

canvas.StrokeColor = Colors.DarkBlue;
canvas.StrokeSize = 4;
canvas.DrawRectangle(10, 10, 100, 100);

在此示例中,绘制尺寸为 100x100 的深蓝色方块, (10,10) :

深蓝色方形的屏幕截图。

有关绘制虚线矩形的信息,请参阅 绘制虚线对象

可以使用方法绘制FillRectangle填充的矩形,该方法还需要x类型float为 :ywidthheight

canvas.FillColor = Colors.DarkBlue;
canvas.FillRectangle(10, 10, 100, 50);

在此示例中,在 (10,10,10) 绘制 100x50 尺寸的深蓝色填充矩形:

深蓝色填充矩形的屏幕截图。

FillColor调用FillRectangle方法之前,必须将对象的属性ICanvas设置为 aColor

注意

DrawRectangle采用和FillRectangleRectF参数的重载Rect

绘制圆角矩形

可以使用方法绘制ICanvasDrawRoundedRectangle圆角矩形和正方形,该方法需要xy类型float、参数widthheightcornerRadius参数。 该 cornerRadius 参数指定用于圆角矩形的半径。

以下示例演示如何绘制圆角矩形:

canvas.StrokeColor = Colors.Green;
canvas.StrokeSize = 4;
canvas.DrawRoundedRectangle(10, 10, 100, 50, 12);

在此示例中,绘制圆角和尺寸为 100x50 的绿色矩形, (10,10) :

绿色圆角矩形的屏幕截图。

有关绘制虚线圆角矩形的信息,请参阅 绘制虚线对象

可以使用方法绘制FillRoundedRectangle填充的圆角矩形,该方法还需要x类型float为 :y、、cornerRadiuswidthheight参数:

canvas.FillColor = Colors.Green;
canvas.FillRoundedRectangle(10, 10, 100, 50, 12);

在此示例中,在 (10,10,10) 绘制带圆角和尺寸 100x50 的绿色填充矩形:

绿色填充圆角矩形的屏幕截图。

FillColor调用FillRoundedRectangle方法之前,必须将对象的属性ICanvas设置为 aColor

注意

DrawRoundedRectangle 一些重 FillRoundedRectangle 载采用 RectRectF 参数,并且重载使每个角的半径可以单独指定。

绘制弧形

可以使用该方法绘制 ICanvas Arc,该方法需要x类型、widthstartAngleheighty类型以及endAngle类型的floatclockwisebool参数和closed参数。DrawArcstartAngle 参数指定从 x 轴到弧线起点的角度。该 endAngle 参数指定从 x 轴到弧线终点的角度。该 clockwise 参数指定绘制弧线的方向,参数 closed 指定弧线的终点是否连接到起点。

以下示例演示如何绘制弧线:

canvas.StrokeColor = Colors.Teal;
canvas.StrokeSize = 4;
canvas.DrawArc(10, 10, 100, 100, 0, 180, true, false);

在此示例中,在 (10,10,10) 绘制尺寸 100x100 的圆弧。 弧线以从 0 度到 180 度的顺时针方向绘制,且未关闭:

圆弧的屏幕截图。

有关绘制虚线弧线的信息,请参阅 绘制虚线对象

可以使用方法绘制FillArc填充弧线,该方法需要x类型、startAngleywidthheight类型float、参数和endAngleclockwise参数:bool

canvas.FillColor = Colors.Teal;
canvas.FillArc(10, 10, 100, 100, 0, 180, true);

在此示例中,在 (10,10,10) 绘制 100x100 的填充圆弧。 弧线以从 0 度到 180 度的顺时针方向绘制,并自动关闭:

填充的圆弧的屏幕截图。

FillColor调用FillArc方法之前,必须将对象的属性ICanvas设置为 aColor

注意

DrawArc采用和FillArcRectF参数的重载Rect

绘制路径

路径是一个或多个 轮廓的集合。 每个轮廓都是 连接的 直线和曲线的集合。 轮廓没有相互连接,但它们可能会直观地重叠。 有时单个轮廓可以重叠本身。

路径用于绘制曲线和复杂形状,并且可以使用需要PathF参数的方法绘制ICanvasDrawPath路径。

轮廓通常以对 PathF.MoveTo 方法的调用开始,该方法可以表示为值,也可以表示为 PointF 单独的 x 坐标 y 。 该 MoveTo 调用在轮廓的开头和初始当前点建立一个点。 然后,可以调用以下方法,以将线条或曲线从当前点继续到方法中指定的点,然后成为新的当前点:

  • LineTo 若要向路径添加直线,则为 。
  • AddArc 如果添加弧线,则为圆或椭圆的周长上的线条。
  • CurveTo 以添加立方贝塞尔样条。
  • QuadTo 以添加二次贝齐尔样条。

这些方法均不包含描述线条或曲线所需的所有数据。 相反,每个方法都适用于方法调用紧靠其前面建立的当前点。 例如,该方法 LineTo 基于当前点向轮廓添加直线。

轮廓以另一个调用 MoveTo结尾,该调用开始新的轮廓,或调用 Close,以关闭轮廓。 该方法 Close 会自动将直线从当前点追加到轮廓的第一个点,并将路径标记为已关闭。

PathF 类还定义其他方法和属性。 以下方法将整个轮廓添加到路径:

  • AppendEllipse 将封闭椭圆轮廓追加到路径。
  • AppendCircle 将封闭圆轮廓追加到路径。
  • AppendRectangle 将封闭矩形轮廓追加到路径。
  • AppendRoundedRectangle 将带圆角的封闭矩形追加到路径。

以下示例演示如何绘制路径:

PathF path = new PathF();
path.MoveTo(40, 10);
path.LineTo(70, 80);
path.LineTo(10, 50);
path.Close();
canvas.StrokeColor = Colors.Green;
canvas.StrokeSize = 6;
canvas.DrawPath(path);

在此示例中,绘制了一个封闭的绿色三角形:

关闭的绿色三角形的屏幕截图。

可以使用填充路径绘制 FillPath,这还需要参数 PathF

PathF path = new PathF();
path.MoveTo(40, 10);
path.LineTo(70, 80);
path.LineTo(10, 50);
canvas.FillColor = Colors.SlateBlue;
canvas.FillPath(path);

在此示例中,绘制填充的石板蓝色三角形:

填充的石板蓝色三角形的屏幕截图。

FillColor在调用FillPath方法之前,必须将对象的属性ICanvas设置为 aColor

重要

该方法 FillPath 具有一个重载,用于指定一个 WindingMode 重载,用于设置使用的填充算法。 有关详细信息,请参阅 “绕行模式”。

绘制图像

可以使用该方法绘制ICanvasDrawImage图像,该方法需要IImage参数floatyxwidth类型参数和height参数。

以下示例演示如何加载图像并将其绘制到画布:

using Microsoft.Maui.Graphics.Platform;
...

IImage image;
Assembly assembly = GetType().GetTypeInfo().Assembly;
using (Stream stream = assembly.GetManifestResourceStream("GraphicsViewDemos.Resources.Images.dotnet_bot.png"))
{
    image = PlatformImage.FromStream(stream);
}

if (image != null)
{
    canvas.DrawImage(image, 10, 10, image.Width, image.Height);
}

警告

Windows 不支持该 PlatformImage 类型。

在此示例中,将从程序集中检索图像,并将其作为流加载。 然后,它以实际大小绘制, (10,10) :

图像的屏幕截图。

重要

加载嵌入在程序集中的映像需要映像将其生成操作设置为 Embedded Resource 而不是 MauiImage

绘制字符串

可以使用其中一个ICanvasDrawString重载绘制字符串。 可以通过设置FontFontColorFontSize属性来定义每个字符串的外观。 可以通过在字符串边界框中执行对齐方式的水平和垂直对齐选项来指定字符串对齐方式。

注意

字符串的边界框由字符串x的边界ywidth框和height参数定义。

以下示例演示如何绘制字符串:

canvas.FontColor = Colors.Blue;
canvas.FontSize = 18;

canvas.Font = Font.Default;
canvas.DrawString("Text is left aligned.", 20, 20, 380, 100, HorizontalAlignment.Left, VerticalAlignment.Top);
canvas.DrawString("Text is centered.", 20, 60, 380, 100, HorizontalAlignment.Center, VerticalAlignment.Top);
canvas.DrawString("Text is right aligned.", 20, 100, 380, 100, HorizontalAlignment.Right, VerticalAlignment.Top);

canvas.Font = Font.DefaultBold;
canvas.DrawString("This text is displayed using the bold system font.", 20, 140, 350, 100, HorizontalAlignment.Left, VerticalAlignment.Top);

canvas.Font = new Font("Arial");
canvas.FontColor = Colors.Black;
canvas.SetShadow(new SizeF(6, 6), 4, Colors.Gray);
canvas.DrawString("This text has a shadow.", 20, 200, 300, 100, HorizontalAlignment.Left, VerticalAlignment.Top);

在此示例中,将显示具有不同外观和对齐选项的字符串:

使用不同对齐选项的字符串的屏幕截图。

注意

DrawString 载还允许指定截断和行距。

有关绘制阴影的信息,请参阅 “绘制阴影”。

绘制特性化文本

可以使用该方法绘制ICanvasDrawText特性化文本,该方法需要一个IAttributedText参数,以及ywidthx类型float参数和height参数。 特性化文本是一个字符串,其中包含其文本部分的相关属性,通常表示样式数据。

以下示例演示如何绘制特性化文本:

using Microsoft.Maui.Graphics.Text;
...

canvas.Font = new Font("Arial");
canvas.FontSize = 18;
canvas.FontColor = Colors.Blue;

string markdownText = @"This is *italic text*, **bold text**, __underline text__, and ***bold italic text***.";
IAttributedText attributedText = MarkdownAttributedTextReader.Read(markdownText); // Requires the Microsoft.Maui.Graphics.Text.Markdig package
canvas.DrawText(attributedText, 10, 10, 400, 400);

在此示例中,markdown 转换为特性化文本,并使用正确的样式显示:

正确呈现 markdown 的屏幕截图。

重要

绘图特性化文本要求你已将 Microsoft.Maui.Graphics.Text.Markdig NuGet 包添加到项目。

用填充和笔划绘制

通过调用填充方法 之后 的绘图方法,可以绘制具有填充和笔划的图形对象到画布。 例如,若要绘制边框,请将 FillColorStrokeColor 属性设置为颜色,然后调用 FillRectangle 方法后跟 DrawRectangle 该方法。

以下示例绘制一个填充的圆圈,其笔划轮廓为路径:

float radius = Math.Min(dirtyRect.Width, dirtyRect.Height) / 4;

PathF path = new PathF();
path.AppendCircle(dirtyRect.Center.X, dirtyRect.Center.Y, radius);

canvas.StrokeColor = Colors.Blue;
canvas.StrokeSize = 10;
canvas.FillColor = Colors.Red;

canvas.FillPath(path);
canvas.DrawPath(path);

在此示例中,指定对象的笔划和填充颜色 PathF 。 绘制填充的圆,然后绘制圆的轮廓笔划:

用填充和笔划绘制的圆圈的屏幕截图。

警告

在填充方法之前调用绘图方法将导致 z 顺序不正确。 填充将绘制在笔划上,并且笔划不会可见。

绘制阴影

在绘图的 ICanvas 图形对象可以使用该方法 SetShadow 应用阴影,该方法采用以下参数:

  • offset类型 SizeF,指定阴影的偏移量,表示创建阴影的光源的位置。
  • blur类型 float,表示要应用于阴影的模糊量。
  • color类型 Color,定义阴影的颜色。

以下示例演示如何向填充对象添加阴影:

canvas.FillColor = Colors.Red;
canvas.SetShadow(new SizeF(10, 10), 4, Colors.Grey);
canvas.FillRectangle(10, 10, 90, 100);

canvas.FillColor = Colors.Green;
canvas.SetShadow(new SizeF(10, -10), 4, Colors.Grey);
canvas.FillEllipse(110, 10, 90, 100);

canvas.FillColor = Colors.Blue;
canvas.SetShadow(new SizeF(-10, 10), 4, Colors.Grey);
canvas.FillRoundedRectangle(210, 10, 90, 100, 25);

在这些示例中,其光源位于不同位置的阴影被添加到填充的对象中,其模糊量相同:

使用阴影绘制的对象屏幕截图。

绘制虚线对象

ICanvas 对象具有一个 StrokeDashPattern 属性,类型 float[]为 . 此属性是一个值数组 float ,指示绘制对象笔划时要使用的短划线和间隔模式。 float数组中的每个值指定短划线或间隙的长度。 数组中的第一项指定短划线的长度,而数组中的第二项指定间隙的长度。 因此, float 具有偶数索引值的值指定短划线,而 float 具有奇数索引值的值指定间隙。

以下示例演示如何使用常规短划线绘制虚线方块:

canvas.StrokeColor = Colors.Red;
canvas.StrokeSize = 4;
canvas.StrokeDashPattern = new float[] { 2, 2 };
canvas.DrawRectangle(10, 10, 90, 100);

在此示例中,绘制有常规虚线笔划的正方形:

常规虚线正方形的屏幕截图。

以下示例演示如何使用不规则短划线绘制虚线的正方形:

canvas.StrokeColor = Colors.Red;
canvas.StrokeSize = 4;
canvas.StrokeDashPattern = new float[] { 4, 4, 1, 4 };
canvas.DrawRectangle(10, 10, 90, 100);

在此示例中,绘制了不规则虚线笔划的正方形:

不规则虚线方块的屏幕截图。

控制线结束

一行有三个部分:开始帽、线条体和尾帽。 开始和结束上限描述行的开始和结束。

ICanvas 对象具有一个 StrokeLineCap 属性,类型 LineCap,用于描述行的开始和结尾。 LineCap 枚举定义下列成员:

  • Butt,表示一条带有正方形的线条,绘制以扩展到该行的确切终结点。 这是 StrokeLineCap 属性的默认值。
  • Round,表示带圆角的线条。
  • Square,表示一条带有正方形的线条,绘制为从端点延伸至行宽等于一半的距离。

下面的示例演示如何设置 StrokeLineCap 属性:

canvas.StrokeSize = 10;
canvas.StrokeColor = Colors.Red;
canvas.StrokeLineCap = LineCap.Round;
canvas.DrawLine(10, 10, 110, 110);

在此示例中,红线在行的开头和末尾舍入:

包含不同行上限的三行的屏幕截图。

控制行联接

ICanvas 对象具有一个 StrokeLineJoin 属性,其类型 LineJoin指定在对象的顶点使用的联接类型。 LineJoin 枚举定义下列成员:

  • Miter,表示产生尖锐或剪裁角的角顶。 这是 StrokeLineJoin 属性的默认值。
  • Round,表示在角上生成圆弧的圆角顶点。
  • Bevel,表示生成对角角的斜顶。

注意

当属性 StrokeLineJoin 设置为 Miter时, MiterLimit 可以将该属性设置为一个 float ,以限制对象中行联接的 miter 长度。

下面的示例演示如何设置 StrokeLineJoin 属性:

PathF path = new PathF();
path.MoveTo(10, 10);
path.LineTo(110, 50);
path.LineTo(10, 110);

canvas.StrokeSize = 20;
canvas.StrokeColor = Colors.Blue;
canvas.StrokeLineJoin = LineJoin.Round;
canvas.DrawPath(path);

在此示例中,蓝色 PathF 对象在其顶点处舍入联接:

三个不同的 LineJoin 枚举成员效果的屏幕截图。

剪辑对象

绘制到绘图 ICanvas 之前的图形对象可以剪裁,方法如下:

  • ClipPath 剪辑对象,以便仅显示对象区域中的区域 PathF
  • ClipRectangle 剪辑对象,以便仅显示矩形区域内的区域。 可以使用参数或Rect参数RectF指定float矩形。
  • SubtractFromClip 剪辑对象,以便只有矩形区域之外的区域可见。 可以使用参数或Rect参数RectF指定float矩形。

以下示例演示如何使用 ClipPath 该方法剪辑图像:

using Microsoft.Maui.Graphics.Platform;
...

IImage image;
var assembly = GetType().GetTypeInfo().Assembly;
using (var stream = assembly.GetManifestResourceStream("GraphicsViewDemos.Resources.Images.dotnet_bot.png"))
{
    image = PlatformImage.FromStream(stream);
}

if (image != null)
{
    PathF path = new PathF();
    path.AppendCircle(100, 90, 80);
    canvas.ClipPath(path);  // Must be called before DrawImage
    canvas.DrawImage(image, 10, 10, image.Width, image.Height);
}

警告

Windows 不支持该 PlatformImage 类型。

在此示例中,图像使用一个 PathF 对象进行剪裁,该对象定义以 80 半径为 100,90 (100,90) 的圆。 结果是只有圆圈中图像的一部分可见:

使用 ClipPath 方法剪裁的图像的屏幕截图。

重要

该方法 ClipPath 具有一个重载,用于指定一 WindingMode 个重载,用于设置剪辑时使用的填充算法。 有关详细信息,请参阅 “绕组”模式

以下示例演示如何使用 SubtractFromClip 该方法剪辑图像:

using Microsoft.Maui.Graphics.Platform;
...

IImage image;
var assembly = GetType().GetTypeInfo().Assembly;
using (var stream = assembly.GetManifestResourceStream("MyMauiApp.Resources.Images.dotnet_bot.png"))
{
    image = PlatformImage.FromStream(stream);
}

if (image != null)
{
    canvas.SubtractFromClip(60, 60, 90, 90);
    canvas.DrawImage(image, 10, 10, image.Width, image.Height);
}

警告

Windows 不支持该 PlatformImage 类型。

在此示例中,由提供给 SubtractFromClip 该方法的参数指定的矩形定义的区域从图像中剪裁。 结果是,只有矩形外部的图像部分可见:

使用 SubtractFromClip 方法剪裁的图像的屏幕截图。