预乘 Alpha
在计算机图形中,有两种不同的方法来表示颜色值的不透明度。 Win2D 使用这两种方法。 本文介绍差异,以及使用位置。
直 alpha
使用直线(也称为线性)alpha 时:
- RGB 值指定正在绘制的内容的颜色
- alpha 值指定其实心程度
在这个世界上,RGB 和 alpha 是独立的。 可以更改一个,而不会影响另一个。 若要使对象淡出,你将逐渐减少其 alpha 值,同时保持 RGB 不变。
若要在使用直线 alpha 格式的两种颜色之间执行源过度混合,请执行以下操作:
result = (source.RGB * source.A) + (dest.RGB * (1 - source.A))
预乘 Alpha
使用预乘 alpha 时:
- RGB 指定所绘制的东西对输出的贡献程度
- alpha 值指定它遮盖其背后的任何内容
在此世界中,RGB 和 alpha 链接。 若要使对象透明,必须减少其 RGB(减少颜色)和 alpha(以掩盖其背后的任何内容)。 完全透明对象根本不具有任何颜色,因此只有一个表示 100% 透明度的值:RGB 和 alpha 全部为零。
若要在使用预乘 alpha 格式的两种颜色之间执行源过度混合,请执行以下操作:
result = source.RGB + (dest.RGB * (1 - source.A))
预乘 alpha 用于图形呈现,因为它在筛选图像或组合不同层时提供比直接 alpha 更好的结果。 有关详细信息,请参阅以下博客文章:
Win2D 中的 Alpha
Win2D 在其 API 图面中使用直接 alpha,但预乘 alpha 用于内部呈现操作。
Windows.UI.Color
值使用直 alpha。 每当将颜色传递给或Draw*
Fill*
方法、设置画笔的颜色或清除到颜色值时,此颜色都使用直线 alpha 指定。
存储在位图或呈现目标中的像素值以及在这些图面上运行的绘图或混合操作使用预乘 alpha。 从文件中加载位图时,其内容会自动转换为预乘格式。 调用 Win2D 绘图方法时,其颜色参数将从直接转换为预乘,然后再进行实际绘图。
Win2D 图像效果使用直线和预乘 alpha 的混合体。 某些效果对一种格式进行操作,一些效果对另一种格式进行操作,有些则提供一个要选择的属性。 每种效果类型的文档描述了它使用哪种 alpha 模式。 效果输入数据始终假定为预乘,因此当某个效果需要使用直 alpha 时,它将首先应用一个不推荐的转换,计算效果,然后重新预乘输出。
位图 API、SetPixelBytes
和GetPixelColors
SetPixelColors
位图 API GetPixelBytes
不执行任何 alpha 格式转换。 它们只是直接将位值传输到基础 GPU 纹理或从基础 GPU 纹理传输。 这样就可以观察 Win2D 在内部使用哪种 alpha 格式:
- 在 rendertarget 上创建绘图会话
- 调用
drawingSession.Clear(Colors.Tranparent)
Colors.Tranparent
定义为 R = 255,G = 255,B = 255,A = 0- Win2D 会将此值转换为预乘格式,生成 R = 0,G = 0,B = 0,A = 0
- 用于
GetPixelColors
读取呈现目标的内容 - 观察它包含预乘格式 RGB = 0,而不是 RGB = 255,如原始直 alpha
Colors.Tranparent
值
在 alpha 格式之间进行转换
若要将直 alpha 颜色值转换为预乘格式,请将其 R、G 和 B 值乘以 A。若要将预乘转换为直线、将 R、G 和 B 除以 A。
请注意,颜色信息通常表示为从 0 到 255 的字节值(例如 Windows.UI.Color
结构包含 4 个字节)。 此表示形式按 255 的因子进行纵向扩展,因此字节值 255 实际表示 1,而 128 为半强度。 在格式转换期间,必须考虑该缩放因子,以便从直接转换为 Windows.UI.Color
预乘:
premultiplied.R = (byte)(straight.R * straight.A / 255);
premultiplied.G = (byte)(straight.G * straight.A / 255);
premultiplied.B = (byte)(straight.B * straight.A / 255);
premultiplied.A = straight.A;
如果你有使用错误 alpha 格式的图像数据, PremultiplyEffect
或者 UnPremultiplyEffect
可用于转换它。