资讯动态

SkiaSharp 2.88.0 macOS 视图 API 演进:PaintSurface 事件参数 Info/RawInfo 重构与迁移指南

发布时间:2026/10/15 18:17:51 来源:尧图企业网站定制
图形学图像处理跨平台【免费下载链接】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 2.88.0 是进入 .NET 6 时代的首个稳定版本其中SkiaSharp.Views.Mac.dll的程序集版本由 2.80.0.0 提升至 2.88.0.0并伴随一次重要的视图事件参数重构SKPaintGLSurfaceEventArgs与SKPaintSurfaceEventArgs新增了以SKImageInfo为核心的构造函数和Info/RawInfo属性同时废弃了携带GRGlFramebufferInfo的旧构造函数。本文以 SkiaSharp.Views.Mac API diff 为骨架结合 SkiaSharp.Views 源码 与 macOS 平台视图实现 逐层拆解这一变更的含义、动机与迁移方法帮助你准确理解Info与RawInfo的区别并顺利将旧代码迁移到新 API。一、变更背景2.88.0 与 .NET 6 时代根据 2.88.0 版本发布说明SkiaSharp 2.88.02022 年 5 月 22 日发布是第一个为 .NET 6 构建的稳定版本带来了 .NET MAUIcompat 与 handlers 两套视图、Mac Catalyst 一等公民支持、WinUI 与 Blazor WebAssembly 组件并将 HarfBuzz 刷新至 2.8.2。视图层SkiaSharp.Views在这次版本中为各平台统一重构了PaintSurface事件的数据承载方式——这正是本文关联文档所记录的 API 变更。值得注意的一点是该变更并非 macOS 独有。对比同目录下的 SkiaSharp.Views.iOS diff 与 SkiaSharp.Views.Android diff 可以看到完全相同的构造函数新增、属性新增与废弃标记。这是因为视图事件参数类本身定义在跨平台共享源码 SKPaintGLSurfaceEventArgs.cs 与 SKPaintSurfaceEventArgs.cs 中通过条件编译符号如__MACOS__、__IOS__、__ANDROID__映射到各自的命名空间macOS 对应SkiaSharp.Views.Mac。因此本文的分析结论可原样套用于 iOS、tvOS、Android、Tizen、Windows 等平台。二、API 变更总览两个事件参数类的完整 diff2.1 SKPaintGLSurfaceEventArgsGL 渲染的事件参数SKPaintGLSurfaceEventArgs用于承载PaintSurface事件的数据适用于 GPU 加速OpenGL渲染路径在 macOS 上由SKGLView与SKGLLayer触发。本次变更包含三类内容废弃的构造函数Obsoleted[Obsolete (Use SKPaintGLSurfaceEventArgs(SKSurface, GRBackendRenderTarget, GRSurfaceOrigin, SKColorType) instead.)] public SKPaintGLSurfaceEventArgs (SkiaSharp.SKSurface surface, SkiaSharp.GRBackendRenderTarget renderTarget, SkiaSharp.GRSurfaceOrigin origin, SkiaSharp.SKColorType colorType, SkiaSharp.GRGlFramebufferInfo glInfo);新增的构造函数Addedpublic SKPaintGLSurfaceEventArgs (SkiaSharp.SKSurface surface, SkiaSharp.GRBackendRenderTarget renderTarget, SkiaSharp.GRSurfaceOrigin origin, SkiaSharp.SKImageInfo info); public SKPaintGLSurfaceEventArgs (SkiaSharp.SKSurface surface, SkiaSharp.GRBackendRenderTarget renderTarget, SkiaSharp.GRSurfaceOrigin origin, SkiaSharp.SKImageInfo info, SkiaSharp.SKImageInfo rawInfo);新增的属性Addedpublic SkiaSharp.SKImageInfo Info { get; } public SkiaSharp.SKImageInfo RawInfo { get; }2.2 SKPaintSurfaceEventArgsCPU 渲染的事件参数SKPaintSurfaceEventArgs服务于 CPU 渲染路径在 macOS 上由SKCanvasView触发。本次变更为其补充了原始图像信息维度新增的构造函数public SKPaintSurfaceEventArgs (SkiaSharp.SKSurface surface, SkiaSharp.SKImageInfo info, SkiaSharp.SKImageInfo rawInfo);新增的属性public SkiaSharp.SKImageInfo RawInfo { get; }两个类均新增了RawInfo属性这正是本次重构的语义核心下文将结合源码详细展开。三、源码级解析构造函数链与 Info/RawInfo 语义3.1 SKPaintGLSurfaceEventArgs 的完整构造函数链在 SKPaintGLSurfaceEventArgs.cs 中可以看到该类现在共有四个构造函数呈链式结构// 便捷入口默认 BottomLeft 原点 Rgba8888 颜色类型 public SKPaintGLSurfaceEventArgs(SKSurface surface, GRBackendRenderTarget renderTarget) : this(surface, renderTarget, GRSurfaceOrigin.BottomLeft, SKColorType.Rgba8888) { } // 显式指定 origin 与 colorTypeInfo 由 renderTarget 尺寸推导 public SKPaintGLSurfaceEventArgs(SKSurface surface, GRBackendRenderTarget renderTarget, GRSurfaceOrigin origin, SKColorType colorType) { Surface surface; BackendRenderTarget renderTarget; ColorType colorType; Origin origin; Info new SKImageInfo(renderTarget.Width, renderTarget.Height, ColorType); RawInfo Info; } // 新增直接以 SKImageInfo 描述表面rawInfo 缺省时与 info 相同 public SKPaintGLSurfaceEventArgs(SKSurface surface, GRBackendRenderTarget renderTarget, GRSurfaceOrigin origin, SKImageInfo info) : this(surface, renderTarget, origin, info, info) { } // 新增info 与 rawInfo 分离可分别描述绘制逻辑尺寸与底层真实尺寸 public SKPaintGLSurfaceEventArgs(SKSurface surface, GRBackendRenderTarget renderTarget, GRSurfaceOrigin origin, SKImageInfo info, SKImageInfo rawInfo) { Surface surface; BackendRenderTarget renderTarget; ColorType info.ColorType; Origin origin; Info info; RawInfo rawInfo; }观察可知几个关键行为ColorType现在从info.ColorType推导而不是像旧 API 那样单独传入若使用三参数的colorType版本Info会自动以renderTarget.Width/Height与传入的ColorType构造GRBackendRenderTarget 的 Width/Height 属性 最终通过gr_backendrendertarget_get_width/heightP/Invoke 获取原生值Info与RawInfo默认相等在colorType版本中两者都指向同一SKImageInfoRawInfo Info三参数的info版本中则通过this(surface, renderTarget, origin, info, info)让两者相同只有五参数版本允许两者分离这也是RawInfo属性真正发挥作用的入口。3.2 SKPaintSurfaceEventArgs 的构造函数链SKPaintSurfaceEventArgs.cs 的逻辑更加简洁public SKPaintSurfaceEventArgs(SKSurface surface, SKImageInfo info) : this(surface, info, info) { } public SKPaintSurfaceEventArgs(SKSurface surface, SKImageInfo info, SKImageInfo rawInfo) { Surface surface; Info info; RawInfo rawInfo; }原先的(surface, info)两参数构造函数被保留并委托给新增的三参数版本RawInfo默认与Info相同向后兼容性得到保证。3.3 Info 与 RawInfo 到底有什么区别从文档注释与源码调用可以确认两者的语义源码注释Info当前表面surface的图像信息即绘制代码应使用的逻辑尺寸——例如在IgnorePixelScaling场景下它对应视图的设备无关尺寸RawInfo底层表面underlying surface的原始图像信息即实际物理像素尺寸与颜色类型用于需要精确感知真实缓冲区大小的场合。在SKCanvasView的 macOS 实现中两者的分离有非常具体的用例详见下节当IgnorePixelScaling开启时Info是视图的 Bounds 尺寸逻辑点而RawInfo是计入BackingScaleFactor后的物理像素尺寸——绘制者用Info定位而底层缓冲区依然以RawInfo为准。四、macOS 平台实测三个视图组件的触发路径4.1 SKGLViewGPU 加速视图NSOpenGLViewSKGLView.cs 是 macOS 上的硬件加速视图继承自NSOpenGLView内部固定使用SKColorType.Rgba8888与GRSurfaceOrigin.BottomLeft。在DrawRect中它按需重建GRBackendRenderTarget与SKSurface随后构造事件参数并触发绘制using (new SKAutoCanvasRestore(canvas, true)) { // 触发 PaintSurface 事件 var e new SKPaintGLSurfaceEventArgs(surface, renderTarget, surfaceOrigin, colorType); OnPaintSurface(e); } // flush 到 OpenGL canvas.Flush(); context.Flush(); OpenGLContext.FlushBuffer();这里的colorType版本构造函数会把Info自动推导为renderTarget的宽高 ×Rgba8888。在事件处理器中你可以通过e.BackendRenderTarget.Width/Height或新的e.Info.Width/Height获取尺寸官方示例注释myView.PaintSurface (sender, e) { var surface e.Surface; var surfaceWidth e.BackendRenderTarget.Width; var surfaceHeight e.BackendRenderTarget.Height; var canvas surface.Canvas; // 在 canvas 上绘制 canvas.Flush(); };4.2 SKGLLayerCore Animation OpenGL 层SKGLLayer.cs 继承自CAOpenGLLayer适合嵌入 Core Animation 层级结构。其DrawInCGLContext方法在每次需要绘制时按Bounds * ContentsScale计算像素尺寸并重建渲染目标最终同样以new SKPaintGLSurfaceEventArgs(surface, renderTarget, surfaceOrigin, colorType)触发事件源码位置绘制完成后调用canvas.Flush()与context.Flush()将内容提交给 OpenGL。4.3 SKCanvasViewCPU 渲染视图——RawInfo 的真实用例SKCanvasView.cs 是 CPU 渲染路径基于 Core Graphics 表面工厂其DrawRect中正是使用了本次新增的五参数/三参数重载来区分逻辑尺寸与物理尺寸using (var surface drawable.CreateSurface(Bounds, Window.BackingScaleFactor, out var info)) { if (info.Width 0 || info.Height 0) { CanvasSize SKSize.Empty; return; } var userVisibleSize IgnorePixelScaling ? new SKSizeI((int)Bounds.Width, (int)Bounds.Height) // 逻辑尺寸 : info.Size; // 物理尺寸 CanvasSize userVisibleSize; if (IgnorePixelScaling) { var skiaCanvas surface.Canvas; skiaCanvas.Scale((float)Window.BackingScaleFactor); skiaCanvas.Save(); } using (var ctx NSGraphicsContext.CurrentContext.CGContext) { // Info 用户可见尺寸RawInfo 底层实际像素尺寸 OnPaintSurface(new SKPaintSurfaceEventArgs(surface, info.WithSize(userVisibleSize), info)); drawable.DrawSurface(ctx, Bounds, info, surface); } }这正是RawInfo引入的典型动机当IgnorePixelScaling为true时Info被WithSize调整为视图的逻辑尺寸绘制代码无需关心像素密度而RawInfo保留了CreateSurface返回的物理像素信息底层缓冲区的真实宽高与颜色类型。这也呼应了 2.88.0 修复的 IgnorePixelScaling 现在按预期工作 这一 Bug Fix——重构后逻辑尺寸与物理尺寸被显式分开不再互相干扰。从源码结构可以推断任何需要以逻辑坐标绘制、但以物理尺寸感知缓冲区的场景都应该读取RawInfo而非Info。五、为什么废弃 glInfo 构造函数diff 中被废弃的构造函数多携带一个GRGlFramebufferInfo glInfo参数[Obsolete(Use SKPaintGLSurfaceEventArgs(SKSurface, GRBackendRenderTarget, GRSurfaceOrigin, SKColorType) instead.)] public SKPaintGLSurfaceEventArgs(SKSurface surface, GRBackendRenderTarget renderTarget, GRSurfaceOrigin origin, SKColorType colorType, GRGlFramebufferInfo glInfo);在当前的共享源码中该构造函数已完全移除GRBackendRenderTarget自身已封装了帧缓冲信息Width、Height、SampleCount、IsValid等均通过 P/Invoke 查询原生句柄见 GRBackendRenderTarget.cs。也就是说glInfo参数在信息表达上是冗余的——renderTarget本身就携带了足够信息同时Info由SKImageInfo统一描述包含宽高、ColorType、AlphaType、ColorSpace见 SKImageInfo.cs比单独传一个颜色类型加一个帧缓冲结构更完整、更一致。这既是 API 精简也是向以SKImageInfo为中心描述表面这一统一模型靠拢。六、迁移指南从旧 API 平滑升级6.1 使用旧的 glInfo 构造函数的代码旧写法2.80 及更早var e new SKPaintGLSurfaceEventArgs(surface, renderTarget, origin, colorType, glInfo);迁移到新 API 的最简形式编译器会提示 Obsolete 警告指向此写法var e new SKPaintGLSurfaceEventArgs(surface, renderTarget, origin, colorType);由于colorType版本内部会自动以renderTarget.Width/Height构造Info行为与旧 API 完全等价。若你需要显式控制颜色类型与透明度例如希望Info携带特定SKAlphaType或SKColorSpace可使用新增的SKImageInfo版本var info new SKImageInfo(renderTarget.Width, renderTarget.Height, colorType, SKAlphaType.Premul); var e new SKPaintGLSurfaceEventArgs(surface, renderTarget, origin, info);6.2 自定义视图/绘制逻辑中使用 RawInfo若你手动构造事件参数并希望区分逻辑尺寸与物理尺寸例如实现自定义的像素缩放绘制使用五参数版本var e new SKPaintGLSurfaceEventArgs( surface, renderTarget, origin, info, // Info绘制逻辑使用的尺寸 rawInfo); // RawInfo底层缓冲区的真实尺寸6.3 事件处理器侧的读取建议绘制布局使用e.Info.Width/e.Info.HeightSKPaintSurfaceEventArgs与SKPaintGLSurfaceEventArgs均可用比e.BackendRenderTarget.Width更直接需要感知真实像素缓冲区如截图、像素级操作、离屏纹理大小时读取e.RawInfoSKPaintGLSurfaceEventArgs的ColorType/Origin属性继续保留与Info/RawInfo并存。七、小结SkiaSharp 2.88.0 对SKPaintGLSurfaceEventArgs与SKPaintSurfaceEventArgs的重构本质上是将表面信息从零散的GRGlFramebufferInfo SKColorType组合收敛为以SKImageInfo为核心、以Info/RawInfo双视角描述表面的统一模型Info面向绘制逻辑RawInfo面向底层真实缓冲区。macOS 的SKCanvasViewCPU、SKGLView与SKGLLayerGPU三套组件均已按新模型触发事件iOS/Android 等其他平台的 diff 与此完全一致迁移成本极低——旧构造函数被[Obsolete]标记但未立即删除编译器会给出明确的方向指引。对于正在升级到 SkiaSharp 2.88.0 的 macOS 应用按照本文第六节的示例替换构造函数即可平滑完成迁移并可立即受益于更准确的尺寸语义。赞分享图形学图像处理跨平台【免费下载链接】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 2.88.0 WinUI 视图 API 解析SKPaintSurfaceEventArgs 的 Info/RawInfo 演进与 PaintSurface 事件实战SkiaSharp 2.88.0 WinUI 视图 API 解析SKPaintSurfaceEventArgs 的 Info/RawInfo 演进与 Pain图形学图像处理跨平台ng-zorro-antd Resizable 实战为 nz-table 表头实现拖拽调整列宽ng zorro antd Resizable 实战为 nz table 表头实现拖拽调整列宽 本指南聚焦于 ng zorro antd 中 resizabl图形学图像处理跨平台SkiaSharp 2.88.0 视图层 API 演进SkiaSharp.Views.UWP 的 SKPaintGLSurfaceEventArgs 与 RawInfo 迁移指南SkiaSharp 2.88.0 视图层 API 演进SkiaSharp.Views.UWP 的 SKPaintGLSurfaceEventArgs 与 Ra图形学图像处理跨平台创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

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

免费获取报价 →
↑