- 图形学
- 图像处理
- 跨平台
【免费下载链接】SkiaSharp
SkiaSharp is a cross-platform 2D graphics API for .NET platforms based on Google's Skia Graphics Library. It provides a comprehensive 2D API that can be used across mobile, server and desktop models to render images.
本文基于 SkiaSharp 仓库中 2.80.2 版本文档 记录的 API 变更,逐一对SkiaSharp.Views.Mac程序集在 2.80.2 中新增的 6 个颜色转换扩展方法进行源码级解析,涵盖SKColorF与CoreGraphics.CGColor、CoreImage.CIColor、AppKit.NSColor之间的双向转换。读完本文,你将理解这些扩展方法的调用签名、底层转换语义(浮点直通 vs 8 位归一化)、平台条件编译差异,并能在 macOS 上把原生 AppKit/CoreGraphics 颜色无缝接入 SkiaSharp 绘图管线。
一、版本变更概览:2.80.2 新增了什么
2.80.2 的 API diff 文档显示,SkiaSharp.Views.Mac.dll中有两个扩展类型发生了变更,均为新增方法(Added methods),没有移除或修改既有 API:
| 扩展类型 | 命名空间 | 新增方法(均为public static) |
|---|---|---|
SkiaSharp.Views.Mac.AppleExtensions | SkiaSharp.Views.Mac | CGColor ToCGColor(this SKColorF color) |
CIColor ToCIColor(this SKColorF color) | ||
SKColorF ToSKColorF(this CGColor color) | ||
SKColorF ToSKColorF(this CIColor color) | ||
SkiaSharp.Views.Mac.MacExtensions | SkiaSharp.Views.Mac | NSColor ToNSColor(this SKColorF color) |
SKColorF ToSKColorF(this NSColor color) |
可以看到,本次变更的核心是补齐了SKColorF(浮点颜色)与 Apple 平台原生颜色类型之间的互转能力。此前AppleExtensions/MacExtensions只针对 8 位SKColor提供互转方法,本次新增则覆盖了浮点颜色通道。
二、SKColorF:SkiaSharp 的浮点颜色结构
要理解这些扩展方法,先要弄清SKColorF是什么。在 SKColorF.cs 中,其类型定义如下:
/// <summary>16-bit, floating-point, ARGB unpremultiplied color value.</summary> public readonly unsafe partial struct SKColorF从生成代码 SKColorF.generated.cs 可以看到,它直接映射 Skia 原生结构sk_color4f_t,采用[StructLayout(LayoutKind.Sequential)]顺序布局,内部由 4 个Single(float)字段组成,分别对应Red、Green、Blue、Alpha通道,通道值为0.0 ~ 1.0 的浮点数:
// sk_color4f_t [StructLayout (LayoutKind.Sequential)] public readonly unsafe partial struct SKColorF : IEquatable<SKColorF> { private readonly Single fR; // public float fR private readonly Single fG; // public float fG private readonly Single fB; // public float fB private readonly Single fA; // public float fA public readonly Single Red => fR; public readonly Single Green => fG; public readonly Single Blue => fB; public readonly Single Alpha => fA; }与之对比,SKColor是 32 位打包的 8 位 ARGB 颜色(见 SKColor.cs,Alpha/Red/Green/Blue均为byte,从uint位移提取)。两者通过运算符转换互相打通:
implicit operator SKColorF(SKColor):每个 8 位通道乘以1f / 255f缩放为浮点(见 SKColorF.cs,源码注释说明这是从原生sk_color4f_from_color移植而来,一次乘法即可与原生路径位级一致,避免每次调用 P/Invoke);explicit operator SKColor(SKColorF):调用SkiaApi.sk_color4f_to_color将浮点颜色转回 8 位颜色(见 SKColorF.cs),此过程存在量化数据损失。
因此,SKColorF适合需要更高颜色精度的场景(如 HDR、渐变计算、着色器参数),而SKColor更适合常规 8 位图像管线。新增的扩展方法正是让这种浮点颜色可以直接与 macOS 原生颜色类型互操作。
三、AppleExtensions:与 CoreGraphics / CoreImage 的颜色互转
AppleExtensions定义在 AppleExtensions.cs,是一个跨平台共享文件,通过条件编译符号在 iOS、tvOS、macOS 三个平台上复用:#if __TVOS__时命名空间为SkiaSharp.Views.tvOS,#elif __IOS__时为SkiaSharp.Views.iOS,#elif __MACOS__时为SkiaSharp.Views.Mac,并把UIColor在 macOS 下别名到AppKit.NSColor:
#if __MACOS__ using UIColor = AppKit.NSColor; #else using UIKit; #endif2.80.2 新增的 4 个方法位于该文件的 CGColor / CIColor 两个区块。
3.1 SKColorF → CGColor(ToCGColor)
public static CGColor ToCGColor(this SKColorF color) { #if __TVOS__ || __IOS__ // see https://bugzilla.xamarin.com/show_bug.cgi?id=44507 return UIColor.FromRGBA(color.Red, color.Green, color.Blue, color.Alpha).CGColor; #else return UIColor.FromRgba(color.Red, color.Green, color.Blue, color.Alpha).CGColor; #endif }实现位于 AppleExtensions.cs。要点:
- 它先把
SKColorF的浮点通道交给UIColor(macOS 下即NSColor)的工厂方法,再取.CGColor属性得到 CoreGraphics 颜色; - 平台差异:iOS/tvOS 使用
UIColor.FromRGBA(大写RGBA),macOS 使用UIColor.FromRgba(小写rgba)——这是因为 macOS 分支中UIColor被别名成了NSColor,二者工厂方法命名不同。源码注释还引用了 Xamarin bug 44507(iOS 下UIColor转CGColor的已知问题规避)。 - 由于
FromRgba接收的是浮点分量(nfloat),SKColorF的 0~1 通道值无需归一化即可直接传入,语义上原生对接。
3.2 CGColor → SKColorF(ToSKColorF)
public static SKColorF ToSKColorF(this CGColor color) => UIColor.FromCGColor(color).ToSKColorF();位于 AppleExtensions.cs。它将CGColor包装成UIColor/NSColor,再借助平台自身的ToSKColorF()扩展(iOS 侧实现在 iOSExtensions.cs,macOS 侧即本文第四节的MacExtensions.ToSKColorF(this NSColor)),从而完成 CoreGraphics → AppKit/UIKit → SkiaSharp 的链路转换。
3.3 SKColorF → CIColor(ToCIColor)
public static CIColor ToCIColor(this SKColorF color) => new CIColor(color.Red, color.Green, color.Blue, color.Alpha);位于 AppleExtensions.cs。这是新增方法中最“直接”的一个:CIColor的构造参数本身就是 0~1 的浮点分量,因此SKColorF的四个通道被原样直通,零转换开销、零精度损失。
作为对照,同文件中对 8 位SKColor的ToCIColor则需要显式归一化(除以 255):
public static CIColor ToCIColor(this SKColor color) => new CIColor(color.Red / 255f, color.Green / 255f, color.Blue / 255f, color.Alpha / 255f);(见 AppleExtensions.cs)。这正体现了新增浮点重载的价值:省去手工除法。
3.4 CIColor → SKColorF(ToSKColorF)
public static SKColorF ToSKColorF(this CIColor color) => UIColor.FromCIColor(color).ToSKColorF();位于 AppleExtensions.cs。与 3.2 类似的桥接式实现:CIColor→UIColor(FromCIColor)→ToSKColorF(),最终得到浮点颜色。
四、MacExtensions:与 AppKit NSColor 的颜色互转
MacExtensions定义在 MacExtensions.cs,命名空间固定为SkiaSharp.Views.Mac,专门处理 AppKit 类型。2.80.2 新增的 2 个方法位于该文件 NSColor 区块。
4.1 NSColor → SKColorF(ToSKColorF)
public static SKColorF ToSKColorF(this NSColor color) { nfloat r, g, b, a; color.GetRgba(out r, out g, out b, out a); return new SKColorF((float)r, (float)g, (float)b, (float)a); }位于 MacExtensions.cs。实现通过NSColor.GetRgba取出 0~1 范围的四个nfloat分量,再直接构造SKColorF,全程保持浮点精度。
同文件中对NSColor的既有ToSKColor(8 位版本)则不同:它把分量乘以 255 并强转byte,存在量化(见 MacExtensions.cs)。新增的浮点版本规避了这层精度损失。
4.2 SKColorF → NSColor(ToNSColor)
public static NSColor ToNSColor(this SKColorF color) => NSColor.FromRgba(color.Red, color.Green, color.Blue, color.Alpha);位于 MacExtensions.cs。NSColor.FromRgba接受 0~1 浮点分量,SKColorF通道直接透传,与既有的ToNSColor(this SKColor)重载(传byte分量)互为补充。
五、精度语义与实现细节剖析
把 6 个新增方法与既有 8 位方法放在一起,可以总结出本仓库的颜色互转设计规律:
- 浮点直通原则:凡是目标类型本身采用 0~1 浮点分量(
CIColor、NSColor.FromRgba),SKColorF通道一律原样传入,不除不乘(见 AppleExtensions.cs、MacExtensions.cs); - 桥接转换:
CGColor/CIColor转SKColorF都经由UIColor/NSColor中转,复用平台自带转换能力,避免手写颜色空间换算(见 AppleExtensions.cs 与 AppleExtensions.cs); - 平台条件编译:同一
AppleExtensions文件通过__IOS__/__TVOS__/__MACOS__三个符号适配三端,其中ToCGColor(SKColorF)对 iOS/tvOS 和 macOS 分别使用FromRGBA与FromRgba(见 AppleExtensions.cs); - 精度对比:
SKColorF通道为float(0~1),SKColor通道为byte(0~255)。往返转换(SKColorF → SKColor → SKColorF)会因 8 位量化产生数据损失;而新增的浮点互转在大多数路径上可做到无损透传。
仓库测试 ColorExtensionsTest.cs 虽针对 HarfBuzz 的HBColor,但其测试模式可印证浮点颜色转换的语义约定:ToSKColorF将 8 位通道归一化为 0~1(如128 / 255f),反向转换则将 0~1 浮点映射回 8 位并对越界值钳制(见 ColorExtensionsTest.cs 与 ColorExtensionsTest.cs)。这有助于理解SKColorF在仓库内的通行用法。
六、实战示例:在 macOS 应用中衔接原生颜色与 SkiaSharp
以 macOS 上的SKCanvasView绘图为例,新增扩展方法可直接消除手写颜色转换样板代码。
场景一:把 AppKit 颜色直接用于 SkiaSharp 绘图
using SkiaSharp; using SkiaSharp.Views.Mac; using AppKit; // 从 AppKit 取颜色(新增 API,2.80.2+) NSColor nsColor = NSColor.SystemBlueColor; SKColorF colorF = nsColor.ToSKColorF(); // 用于 SkiaSharp 绘制 using var paint = new SKPaint { Color = (SKColor)colorF }; canvas.DrawCircle(100, 100, 50, paint);场景二:把 SkiaSharp 浮点颜色回写到 AppKit / CoreImage / CoreGraphics
SKColorF skColorF = new SKColorF(0.2f, 0.4f, 0.8f, 1.0f); // 20% 红、40% 绿、80% 蓝 NSColor nsColor = skColorF.ToNSColor(); // AppKit CIColor ciColor = skColorF.ToCIColor(); // CoreImage(浮点直通) CGColor cgColor = skColorF.ToCGColor(); // CoreGraphics(经 NSColor 桥接)这些示例中的类型与调用均来自仓库中已验证的公开 API(AppleExtensions.cs 与 MacExtensions.cs),可直接在引用SkiaSharp.Views的 macOS 项目中编译运行。注意SkiaSharp.Views.Mac程序集仅在 macOS 目标下可用,使用前请确认项目 TargetFramework 包含 macOS 平台。
七、小结与源码导航
2.80.2 的这次 API 变更为SKColorF补齐了 Apple 生态三套颜色类型(AppKitNSColor、CoreGraphicsCGColor、CoreImageCIColor)的双向转换能力,使 macOS 上的 SkiaSharp 开发者可以用浮点精度在原生 UI 颜色与 Skia 颜色管线之间自由切换,同时保持与 iOS/tvOS 共享实现的代码一致性。
如需深入阅读,可按以下路径继续探索:
- 版本变更原始记录:SkiaSharp.Views.Mac.md
- 共享扩展实现(含全部颜色/图像转换):AppleExtensions.cs
- macOS 专属扩展实现:MacExtensions.cs
- iOS/tvOS 对照实现:iOSExtensions.cs
- 浮点颜色结构定义与运算符转换:SKColorF.cs、SKColorF.generated.cs
- 8 位颜色结构定义:SKColor.cs
- 颜色转换语义相关测试:ColorExtensionsTest.cs
- 图形学
- 图像处理
- 跨平台
【免费下载链接】SkiaSharp
SkiaSharp is a cross-platform 2D graphics API for .NET platforms based on Google's Skia Graphics Library. It provides a comprehensive 2D API that can be used across mobile, server and desktop models to render images.
相关推荐
SkiaSharp 2.80.2 新增 SKColorF 颜色转换扩展:tvOS/iOS 平台 UIKit、CoreGraphics、CoreImage 与 Skia 颜色的无缝互转
SkiaSharp 2.80.2 新增 SKColorF 颜色转换扩展:tvOS/iOS 平台 UIKit、CoreGraphics、CoreImage 与 S
图形学图像处理跨平台SkiaSharp 2.80.2 新增 SKColorF 颜色转换 API:iOS / tvOS 平台 UIKit、CoreGraphics 与 CoreImage 颜色互转指南
SkiaSharp 2.80.2 新增 SKColorF 颜色转换 API:iOS / tvOS 平台 UIKit、CoreGraphics 与 CoreIma
图形学图像处理跨平台SkiaSharp 2.80.2 API 解析:Xamarin.Forms 与 SKColorF 颜色互转扩展方法及 GTK 渲染器原生控件创建
SkiaSharp 2.80.2 API 解析:Xamarin.Forms 与 SKColorF 颜色互转扩展方法及 GTK 渲染器原生控件创建 SkiaSha
图形学图像处理跨平台
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考