本文为个人博客备份文章,原文地址:
http://validvoid.net/win2d-premultiplied-alpha/
在计算机绘图中有两种表示颜色值不透明度的方法。Win2D 中两种方法均有所采用。本文旨在解释两种方法之间的区别以及其各自的使用场景。
当使用直接,亦即线性 Alpha 时:
在该方法中,RGB 和 Alpha 通道各自独立发挥作用。它们可以在不互相影响的情况下各自发生改变。要使一个对象淡出,只需保持 RGB 取值不变,逐步减小 Alpha 值即可。
以直接 Alpha 格式实现两种颜色的 Source-over 模式混合:
结果 = (源.RGB * 源.A) + (目标.RGB * (1 - 源.A))
当使用预乘 Alpha 时:
在该方法中,RGB 通道和 Alpha 通道相关联。要使对象透明,则必须同时减少 RGB 值(减少颜色浓度)和 Alpha 值(减轻对背景内容的掩藏幅度)。完全透明的对象不具有任何颜色,所以只有一个值表示 100% 的透明度:RGB 和 Alpha 值均为零。
以预乘 Alpha 格式实现两种颜色的 Source-over 模式混合:
结果 = 源.RGB + (目标.RGB * (1 - 源.A))
在图形渲染领域,进行图像过滤或多图层组合时通常应用预乘 Alpha 方法,因为相比直接 Alpha 其效果更好。更多信息可以参见:
Win2D 在 API 层次上使用直接 Alpha,而在内部渲染操作中使用预乘 Alpha。
Windows.UI.Color
值为直接 Alpha。 当你向 Draw
* 或 Fill
* 方法传递一个颜色参数、设置画刷的颜色或以某个颜色清屏时,该颜色使用的都是直接 Alpha。
储存在一个位图(bitmap)或者渲染目标(rendertarget)中的像素值,以及在此层次上进行的绘制或混合操作均使用预乘 Alpha。当位图从文件中加载时,其内容会自动转为预乘格式。当你调用一个 Win2D 绘图方法时,其颜色参数也会在绘图实际发生前从直接转换到预乘。
Win2D 图像特效混合使用直接和预乘 Alpha。部分特效使用其中一种格式,其它特效使用另一种格式,还有些特效提供了一个属性以供选择。每种特效类型的文档均有描述该特效使用哪种 Alpha 模式。特效的输入数据总是会被假定为预乘格式,所以当一个特效要应用直接 Alpha,它会先执行一次反预乘变换,然后计算特效,最后在重新进行预乘输出。
GetPixelBytes
、 SetPixelBytes
、 GetPixelColors
以及 SetPixelColors
等位图 API 并不 进行任何 Alpha 格式转换。它们进在底层 GPU 纹理与上层对象之间直接传递位值。通过以下方法可以观察到 Win2D 内部是如何处理 Alpha 格式的:
drawingSession.Clear(Colors.Tranparent)
Colors.Tranparent
的定义为 R=255, G=255, B=255, A=0GetPixelColors
读回 rendertarget 的内容Colors.Tranparent
值 RGB=255要把直接 Alpha 格式的颜色转换为预乘 Alpha 格式,将颜色的 R、G、B 三值分别乘以 A 值。要从预乘 Alpha 转换为直接 Alpha,则将 R、G、B 三值分别除以 A 值。
注意颜色信息通常以取值范围从 0 到 255 的字节值表示(例如 Windows.UI.Color
结构由 4 个字节组成)。这一表示以 255 为换算系数按比变化,故字节值 255 即表示 1,而 128 即表示一半程度。在进行格式转换时,必须带入换算系数参与计算,因此将一个 Windows.UI.Color
从直接转换到预乘的计算过程为:
预乘值.R = (byte)(直接值.R * 直接值.A / 255);
预乘值.G = (byte)(直接值.G * 直接值.A / 255);
预乘值.B = (byte)(直接值.B * 直接值.A / 255);
预乘值.A = 直接值.A;
如果现有图像数据的 Alpha 格式不正确,可以使用 PremultiplyEffect 或UnPremultiplyEffect 特效进行转换。
原文:http://www.cnblogs.com/validvoid/p/win2d-premultiplied-alpha.html