资讯动态

SkiaSharp 基础绘图实战:在 .NET MAUI 中绘制一个简单圆形

发布时间:2026/10/13 6:34:53 来源:尧图企业网站定制
图形学图像处理跨平台【免费下载链接】SkiaSharpSkiaSharp is a cross-platform 2D graphics API for .NET platforms based on Googles Skia Graphics Library. It provides a comprehensive 2D API that can be used across mobile, server and desktop models to render images.项目地址https://gitcode.com/gh_mirrors/sk/SkiaSharp点击查看免费下载本指南以 SkiaSharp 官方文档“Drawing Basics”系列中的Simple Circle示例为线索系统讲解在 .NET MAUI 应用中绘制 2D 图形所必需的三个核心构件承载绘图的SKCanvasView视图、负责重绘回调的PaintSurface事件以及定义颜色与线条属性的SKPaint对象。读完本文你将掌握“描边圆形轮廓 填充圆形内部”这一最经典的 SkiaSharp 绘制流程并能从源码层面理解SKSurface、SKCanvas、SKImageInfo之间的协作关系。绘制目标一个红边蓝心的圆示例页面要完成的效果非常直观在页面正中央绘制一个半径为 100 像素的圆圆的外部轮廓为红色描边宽度 25 像素圆的内部填充为蓝色。由于这个图形同时包含两种颜色绘制必须分两步完成——先用Stroke样式描出轮廓再切换为Fill样式填充内部两次调用同一个DrawCircle方法。示例页面类为SimpleCirclePage它派生自 MAUI 的ContentPage并在文件顶部引入了两个 SkiaSharp 命名空间using SkiaSharp; using SkiaSharp.Views.Maui.Controls;其中SkiaSharp提供全部绘图 APISKCanvas、SKPaint、SKColor等而SkiaSharp.Views.Maui.Controls则提供与 .NET MAUI 集成的视图控件SKCanvasView及颜色扩展方法。第一步创建 SKCanvasView 并订阅 PaintSurface绘图的第一步是创建一个SKCanvasView对象来承载图形。它本质上是 SkiaSharp 提供给 MAUI 的“画布宿主控件”在仓库中SKCanvasView.cs 将其定义为public partial class SKCanvasView : View, ISKCanvasView也就是说它本身就是一个标准的 MAUIView可以像其他视图一样参与页面布局甚至与其他 MAUI 控件混排。public SimpleCirclePage() { Title Simple Circle; SKCanvasView canvasView new SKCanvasView(); canvasView.PaintSurface OnCanvasViewPaintSurface; Content canvasView; }这段代码做了三件事设置页面标题、为PaintSurface事件挂接处理函数、把画布视图设为页面内容。此时SKCanvasView会占据页面整个内容区域你也可以在 XAML 中声明它甚至与其他 MAUIView组合布局。所有绘图都发生在 PaintSurface 事件里PaintSurface是 SkiaSharp 视图控件的核心事件所有绘制代码都必须写在这个事件的处理函数中。它并不只在首次显示时触发一次——窗口大小变化、页面重新布局、调用InvalidateSurface手动请求重绘等场景都会再次触发它。因此处理函数必须是无状态的它应当根据每次传入的参数尤其是画布尺寸重新构建完整画面而不是依赖上一次调用留下的中间状态。void OnCanvasViewPaintSurface(object? sender, SKPaintSurfaceEventArgs args) { ... }事件参数Info 与 SurfacePaintSurface的事件参数类型为SKPaintSurfaceEventArgs。在仓库源码 SKPaintSurfaceEventArgs.cs 中它封装了两个核心只读属性属性类型含义InfoSKImageInfo描述绘图表面的尺寸与像素格式最重要的是以像素为单位的宽和高SurfaceSKSurface绘图表面本身代表一块可绘制的画布SKSurface表示“绘制到哪里去”的目标。在本例中绘图表面就是屏幕上的视频显示区域但在其他程序中同一个SKSurface也可以代表一张位图——这正是 SkiaSharp 既能做屏幕渲染、又能离屏绘制图片的底层原因。SKImageInfo则是一个描述图像尺寸和像素类型的结构体。查看 SKImageInfo.cs 源码可以发现除Width、Height之外它还携带ColorType像素颜色类型如Rgba8888/Bgra8888、AlphaType透明度类型和ColorSpace色彩空间等信息并提供BytesSize、RowBytes等内存布局计算属性。值得留意的是事件参数中还包含一个RawInfo属性。从源码注释可知当SKCanvasView.IgnorePixelScaling为true时Info返回用户可见的逻辑尺寸而RawInfo始终返回物理像素尺寸在高 DPI 屏幕上两者往往并不相等。第二步获取 SKCanvas 并清屏SKSurface上最重要的属性是Canvas类型为SKCanvas。SKCanvas是真正的“绘图上下文”所有图形绘制操作都由它完成它同时封装了图形状态包括变换transform和裁剪clip。在 SKSurface.cs 源码中Canvas属性通过SkiaApi.sk_surface_get_canvas(Handle)获取底层 Skia 画布对象。一个典型的PaintSurface处理函数开头如下void OnCanvasViewPaintSurface(object? sender, SKPaintSurfaceEventArgs args) { SKImageInfo info args.Info; SKSurface surface args.Surface; SKCanvas canvas surface.Canvas; canvas.Clear(); ... }canvas.Clear()用透明色清空整个画布为新一轮绘制提供干净的起点。从 SKCanvas.cs 源码可以看到Clear()无参版本等价于Clear(SKColors.Empty)而SKColors.Empty在 SKColors.cs 中定义为new SKColor(0x00000000)即全透明重载版本Clear(SKColor color)则允许你指定一个背景色。底层分别通过sk_canvas_clear与sk_canvas_clear_color4f调用 Skia 原生库。第三步用 SKPaint 描出红色轮廓SKPaint是 SkiaSharp 中定义“如何绘制”的对象——它几乎就是一组绘图属性的集合颜色、样式、线宽、抗锯齿等。第一步先描边void OnCanvasViewPaintSurface(object? sender, SKPaintSurfaceEventArgs args) { ... SKPaint paint new SKPaint { Style SKPaintStyle.Stroke, Color Colors.Red.ToSKColor(), StrokeWidth 25 }; ... }StyleStroke 与 Fill 的差别Style属性决定图形是描边stroke还是填充fill。枚举SKPaintStyle在 SKPaintStyle.generated.cs 中定义共三个成员直接对应原生 Skia 的sk_paint_style_t成员原生值含义Fill0只填充几何图形内部默认值Stroke1只描边几何图形轮廓StrokeAndFill2既描边又填充且两者使用同一颜色这里把Style设为Stroke因此后续绘制的圆只有轮廓、没有内部填充。ColorMAUI 颜色与 SKColor 的转换Color属性要求SKColor类型的值。SKColor是 SkiaSharp 的颜色结构体ARGB 各 8 位。把 .NET MAUI 的Color转成SKColor的推荐方式是调用扩展方法ToSKColor。其实现位于 Extensions.cspublic static SKColor ToSKColor(this Color color) new SKColor((byte)(color.Red * 255), (byte)(color.Green * 255), (byte)(color.Blue * 255), (byte)(color.Alpha * 255));可以看到它把 MAUIColor的 0~1 浮点通道值线性映射到 0~255 的字节范围。Extensions类中还提供了ToSKColorF等其他 MAUI 与 SkiaSharp 之间的转换方法。StrokeWidth描边宽度StrokeWidth指定线条粗细本例设为 25 像素。从 SKPaint.cs 源码看它通过sk_paint_get_stroke_width/sk_paint_set_stroke_width与原生 Skia 交互默认值为 0此时描边使用约 1 像素的细线。第四步调用 DrawCircle 绘制轮廓准备好SKPaint之后就可以调用SKCanvas.DrawCircle绘制圆形void OnCanvasViewPaintSurface(object? sender, SKPaintSurfaceEventArgs args) { ... canvas.DrawCircle(info.Width / 2, info.Height / 2, 100, paint); ... }DrawCircle在 SKCanvas.cs 中有两个重载DrawCircle(float cx, float cy, float radius, SKPaint paint)和DrawCircle(SKPoint c, float radius, SKPaint paint)后者内部会转发到前者。其参数含义如下前两个参数圆心的 X、Y 坐标第三个参数圆半径本例固定 100 像素最后一个参数携带样式属性的SKPaint对象。这里用info.Width / 2和info.Height / 2计算画布宽高的一半从而把圆心放在显示区域的中心。坐标系约定SkiaSharp 的坐标系以显示表面左上角为原点 (0, 0)X 轴向右递增Y 轴向下递增。这一点与数学中常见的坐标系Y 轴向上方向相反初学者最容易混淆。在本文系列中坐标均指像素坐标。第五步切换属性填充蓝色内部第二步绘制改用Fill样式填充圆内部。示例巧妙地复用同一个SKPaint对象——只修改它的Style和Color两个属性然后再次调用DrawCirclevoid 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); }这里展示了获取SKColor的另一种方式直接使用SKColors结构体中预定义的颜色字段。在 SKColors.cs 中SKColors.Blue定义为new SKColor(0xFF0000FF)不透明纯蓝此外还有AliceBlue、BlueViolet等 140 余种预置颜色可直接选用。深入理解为什么 PaintSurface 会被反复调用当你旋转手机或调整模拟器方向时图形会被自动重绘——这正是PaintSurface事件机制的意义所在每次需要重绘时事件都会重新触发处理函数依据最新的args.Info尺寸重建画面。在本系列后续的 integration.md 中你会看到更主动的用法在触摸事件处理函数中调用SKCanvasView.InvalidateSurface()来手动触发一次PaintSurface重绘从而实现“点击切换圆形填充与否”的交互效果。实用建议抗锯齿与 SKPaint 复用抗锯齿SKPaint类提供IsAntialias属性见 SKPaint.cs底层为sk_paint_is_antialias。开启后图形边缘会明显更平滑因此绝大多数实际项目中都建议将其设为true。出于示例简洁性的考虑本文示例页面没有设置它。SKPaint 是轻量对象它本质上只是一组绘图属性的集合。你可以像本示例一样反复修改并复用同一个对象也可以为不同的属性组合创建多个SKPaint对象还可以在PaintSurface事件之外创建和初始化它们并作为字段保存在页面类中避免每帧重绘时重复构造。补充原理25 像素的描边为何看起来更细细心的读者会发现虽然轮廓宽度被设置为 25 像素圆半径的 1/4但最终效果看起来比 25 像素更细。原因在于DrawCircle的参数定义的是抽象几何坐标而描边线以该几何圆为基准向两侧对称展开——一半宽度在圆内侧一半在圆外侧。蓝色内部填充恰好覆盖了内侧那一半约 12.5 像素所以可见的红色轮廓只剩外侧的一半。这一点会在 integration.md 的示例中通过可视化方式进一步展示。相关链接SkiaSharp 绘图基础系列索引包含像素与设备无关单位、基础动画、文本集成、位图基础与透明度等进阶主题与 .NET MAUI 集成通过触摸交互与 MAUI 控件组合创建可交互的 SkiaSharp 图形SKCanvasView 控件实现MAUI 视图层封装与IgnorePixelScaling绑定属性SKPaintSurfaceEventArgs 事件参数Info/Surface/RawInfo的完整定义SKCanvas 绘图方法Clear、DrawCircle等绘制的底层调用SKPaint 属性定义Style、Color、StrokeWidth、IsAntialias赞分享图形学图像处理跨平台【免费下载链接】SkiaSharpSkiaSharp is a cross-platform 2D graphics API for .NET platforms based on Googles Skia Graphics Library. It provides a comprehensive 2D API that can be used across mobile, server and desktop models to render images.项目地址https://gitcode.com/gh_mirrors/sk/SkiaSharp点击查看免费下载相关推荐使用SkiaSharp绘制复杂图形.NET MAUI高级可视化使用SkiaSharp绘制复杂图形.NET MAUI高级可视化 概述 在跨平台应用开发中实现高性能、高质量的图形绘制一直是开发者面临的挑战。.NET MAU前端移动开发桌面应用跨平台UI组件flet.canvas.Arc 绘图详解在 Flet 中绘制圆弧、扇形与圆环的完整指南flet.canvas.Arc 绘图详解在 Flet 中绘制圆弧、扇形与圆环的完整指南 导读 flet.canvas.Arc 是 Flet 内置画布Canv前端跨平台桌面应用移动开发PaddleSpeech 标点恢复paddlespeech.text.models.ernie_linear 模块源码级解析与实战指南PaddleSpeech 标点恢复paddlespeech.text.models.ernie_linear 模块源码级解析与实战指南 本文围绕 Paddle图形学图像处理跨平台上一篇Pylint redefined-builtinW0622检查详解内置名称遮蔽的规则、例外与配置下一篇如何高效使用Legacy iOS Kit面向开发者的完整iOS设备降级与越狱终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑