本文为个人博客备份文章,原文地址:

http://validvoid.net/win2d-premultiplied-alpha/

在计算机绘图中有两种表示颜色值不透明度的方法。Win2D 中两种方法均有所采用。本文旨在解释两种方法之间的区别以及其各自的使用场景。

直接 Alpha (Straight alpha)

当使用直接,亦即线性 Alpha 时:

  • RGB 值指定绘制目标的颜色
  • Alpha 值指定绘制目标的质密程度

在该方法中,RGB 和 Alpha 通道各自独立发挥作用。它们可以在不互相影响的情况下各自发生改变。要使一个对象淡出,只需保持 RGB 取值不变,逐步减小 Alpha 值即可。

以直接 Alpha 格式实现两种颜色的 Source-over 模式混合:

结果 = (源.RGB * 源.A) + (目标.RGB * (1 - 源.A))

预乘 alpha (Premultiplied alpha)

当使用预乘 Alpha 时:

  • RGB 指定绘制目标输出时绘制的颜色量
  • Alpha 值指定背景内容的掩藏程度

在该方法中,RGB 通道和 Alpha 通道相关联。要使对象透明,则必须同时减少 RGB 值(减少颜色浓度)和 Alpha 值(减轻对背景内容的掩藏幅度)。完全透明的对象不具有任何颜色,所以只有一个值表示 100% 的透明度:RGB 和 Alpha 值均为零。

以预乘 Alpha 格式实现两种颜色的 Source-over 模式混合:

结果 = 源.RGB + (目标.RGB * (1 - 源.A))

在图形渲染领域,进行图像过滤或多图层组合时通常应用预乘 Alpha 方法,因为相比直接 Alpha 其效果更好。更多信息可以参见:

Win2D 中的 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 格式的:

  • 对一个 rendertarget 创建一个 drawing session
  • 调用 drawingSession.Clear(Colors.Tranparent)
  • Colors.Tranparent 的定义为 R=255, G=255, B=255, A=0
  • Win2D 会把此透明颜色值转换为预乘值,即 R=0, G=0, B=0, A=0
  • 使用 GetPixelColors 读回 rendertarget 的内容
  • 观察读取的内容包含的颜色值为预乘的 RGB=0, 而非原先直接 Alpha 格式的 Colors.Tranparent 值 RGB=255

在 Alpha 格式之间进行转换

要把直接 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 特效进行转换。

Win2D 官方文章系列翻译 - 预乘 Alpha的更多相关文章

  1. Win2D 官方文章系列翻译 - 像素格式

    本文为个人博客备份文章,原文地址: http://validvoid.net/win2d-pixel-formats/ DirectXPixelFormat 枚举 包含了 Direct3D 和 DXG ...

  2. Win2D 官方文章系列翻译 - 处理设备丢失

    本文为个人博客备份文章,原文地址: http://validvoid.net/win2d-handling-device-lost/ “设备丢失”是指 GPU 设备失效无法继续进行渲染的情况.GPU ...

  3. Win2D 官方文章系列翻译 - DPI (每英寸点数)和 DIPs(设备独立像素)

    本文为个人博客备份文章,原文地址: http://validvoid.net/win2d-dpi-dips/ 本文旨在解释物理像素与设备独立像素(DIPs, device independent pi ...

  4. Win2D 官方文章系列翻译 - 避免内存泄漏

    本文为个人博客备份文章,原文地址: http://validvoid.net/win2d-avoiding-memory-leaks/ 在托管 XAML 应用中使用 Win2D 控件时,必须谨慎处理对 ...

  5. Win2D 官方文章系列翻译 - 幕后绘制

    本文为个人博客备份文章,原文地址: http://validvoid.net/win2d-offscreen-drawing/ 应用有时需要将图形绘制到并不立即显示的目标上.此类绘制动作被称作“幕后绘 ...

  6. Win2D 官方文章系列翻译 - 与 Direct2D 互操作

    本文为个人博客备份文章,原文地址: http://validvoid.net/win2d-interop-with-direct2d/ Win2D 作为 Direct2D 的上层实现,支持与其进行双向 ...

  7. Win2D 官方文章系列翻译 - 调整控件分辨率

    本文为个人博客备份文章,原文地址: http://validvoid.net/win2d-choosing-control-resolution/ 本文旨在讲解如何配置 Win2D XAML 控件使用 ...

  8. NLog文章系列——如何配置NLog(转)

    NLog使用方法 作者:Jaros?aw Kowalski <> 翻译:CrazyCoder(由衷感谢他的热心!!) 原文:http://www.nlog-project.org/conf ...

  9. AngularJS系列-翻译官网

    公司之前一直用的Web前台框架是Knockout,我们通常直接叫ko,有看过汤姆大叔的KO系列,也有在用,发现有时候用得不太顺手.本人是会WPF的,所以MVVM也是比较熟悉的,学ko也是很快就把汤姆大 ...

随机推荐

  1. xunsearch

    xunsearch 1.wget http://www.xunsearch.com/download/xunsearch-full-latest.tar.bz2 2.解压 tar -jxvf xuns ...

  2. pip_install的安装

    1.下载get-pip.py https://pip.pypa.io/en/latest/installing/#id9 2.运行 python get-pip.py 3.python -m pip ...

  3. Flink生态与未来

    本文为<Flink大数据项目实战>学习笔记,想通过视频系统学习Flink这个最火爆的大数据计算框架的同学,推荐学习课程: Flink大数据项目实战:http://t.cn/EJtKhaz ...

  4. Jenkins项目部署使用教程-----03节点添加

    1)添加节点 系统管理——>管理节点——>新建节点 进入配置界面 点ok进入配置界面配置,——>高级 点击save保存,进入节点,点击Launch agent使得jenkins服务器 ...

  5. docker 安装 redis

    docker拉去镜像以及配置生成容器的步骤几乎和之前的nginx安装一样,直接写下面的命令了 1. docker pull redis 2. docker run -p 6379:6379 -v /U ...

  6. centos6+如何对外开放80,3306端口号或者其他端口号

    1.查看防火墙对外开放了哪些端口 [root@hadoop110 ~]# iptables -L -n Chain INPUT (policy ACCEPT) target prot opt sour ...

  7. 30 个 Java 集合面试问题及答案

    30 个 Java 集合面试问题及答案 Java集合框架为Java编程语言的基础,也是Java面试中很重要的一个知识点.这里,我列出了一些关于Java集合的重要问题和答案. 1.Java集合框架是什么 ...

  8. os模块与 sys模块

    os模块是与操作系统交互的一个接口 ''' os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作 ...

  9. zTree学习笔记

    一.zTree的下载 官网:http://www.treejs.cn/v3/main.php#_zTreeInfo 解压后的目录结构为: 二.zTree入门案例 2.1 在页面中引入相关文件 要使用z ...

  10. python期中总结

    1.tuple 元组 与列表类似 tup1 = (12, 34.56) tup2 = ('abc', 'xyz') # 以下修改元组元素操作是非法的. # tup1[0] = 100 # 创建一个新的 ...