SkiaSharp 混合模式

这些文章重点介绍 SKPaintBlendMode 属性。 BlendMode 属性的类型为 SKBlendMode,它是具有 29 个成员的枚举。

BlendMode 属性确定当图形对象(通常称为源)呈现在现有图形对象(称为目标)之上时会发生什么情况。 通常,我们预期新图形对象会遮挡其下方的对象。 但出现这种情况只是因为默认混合模式为 SKBlendMode.SrcOver,这意味着源是在目标的上方绘制的SKBlendMode 的其他 28 个成员会产生其他影响。 在图形编程中,以各种方式组合图形对象的方法称为合成

SKBlendModes 枚举

SkiaSharp 混合模式与 W3C 合成和混合级别 1 规范中所述的模式密切相关。 Skia SkBlendMode 概述还提供了有用的背景信息。 如需混合模式的一般介绍,可以从维基百科中的混合模式一文着手。 Adobe Photoshop 支持混合模式,因此有很多有关该上下文中混合模式的其他在线信息。

SKBlendMode 枚举的 29 个成员可以分为三种类别:

Porter-Duff 可分离 不可分离
Clear Modulate Hue
Src Screen Saturation
Dst Overlay Color
SrcOver Darken Luminosity
DstOver Lighten
SrcIn ColorDodge
DstIn ColorBurn
SrcOut HardLight
DstOut SoftLight
SrcATop Difference
DstATop Exclusion
Xor Multiply
Plus

这三个类别的名称在接下来的讨论中具有更多含义。 此处列出的成员的顺序与 SKBlendMode 枚举定义中的顺序相同。 第一列中的 13 个枚举成员的整数值为 0 到 12。 第二列是对应于整数 13 到 24 的枚举成员,第三列中的成员的值为 25 到 28。

这些混合模式在 W3C“合成与混合级别 1”文档中讨论的顺序大致相同,但存在一些差异:Src 模式在 W3C 文档中称为“复制”,Plus 称为“照明器”。 W3C 文档定义了一种“正常”混合模式,该模式未包含在 SKBlendModes 中,因为它与 SrcOver 相同Modulate 混合模式(位于第二列的顶部)未包含在 W3C 文档中,并且 Multiply 模式的讨论优先于 Screen

由于 Modulate 混合模式是 Skia 所独有的,因此我们将其作为附加 Porter-Duff 模式和可分离模式进行讨论。

透明度的重要性

从历史上讲,合成是与 alpha 通道的概念结合开发出来的。 在显示表面(例如 SKCanvas 对象和全色位图)中,每个像素由 4 个字节组成:红色、绿色和蓝色分量各 1 个字节,以及一个用于透明度的附加字节。 此 alpha 分量为 0 表示完全透明,0xFF 表示完全不透明,这些值之间具有不同级别的透明度。

许多混合模式依赖于透明度。 通常,首次在 PaintSurface 处理程序中获取 SKCanvas 时,或者在创建 SKCanvas 以在位图上绘制时,第一步是发出此调用:

canvas.Clear();

此方法将画布的所有像素替换为透明黑色像素,等效于 new SKColor(0, 0, 0, 0) 或整数 0x00000000。 所有像素的所有字节都初始化为零。

PaintSurface 处理程序中获取的 SKCanvas 的绘图表面可能看起来具有白色背景,但这只是因为 SKCanvasView 本身具有透明背景,并且页面具有白色背景。 可以通过将 SKCanvasView 的 Xamarin.FormsBackgroundColor 属性设置为 Xamarin.Forms 颜色来亲自演示这一事实:

canvasView.BackgroundColor = Color.Red;

或者,在派生自 ContentPage 的类中,可以设置页面背景色:

BackgroundColor = Color.Red;

你将在 SkiaSharp 图形后面看到红色背景,因为 SkiaSharp 画布本身是透明的。

SkiaSharp 透明度一文介绍了使用透明度在合成图像中排列多个图形的一些基本方法。 混合模式不仅限于此,但透明度对于混合模式仍然至关重要。

SkiaSharp Porter-Duff 混合模式

使用 Porter-Duff 混合模式可以根据源图像和目标图像合成场景。

SkiaSharp 可分离混合模式

使用可分离混合模式可以改变红色、绿色和蓝色。

SkiaSharp 不可分离混合模式

使用不可分离混合模式可以改变色调、饱和度或亮度。