图形混合概念
Posted tiantian-t
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图形混合概念相关的知识,希望对你有一定的参考价值。
alpha混合与porter/duff
稍微接触过一点图形相关应用的人应该都会知道alpha混合,再深入一点就应该会看到porter, duff两位神人的名字,他们是最早在SIGGRAPH上提出图形混合概念的前辈。
对于alpha混合,最简单的说法是Src*alpha + Dst*(1-alpha),至少这是我第一次了解到的alpha算法,但事实上porter, duff提出的混合远比这个复杂。因为每次都会忘记他们提出的那12个混合方式是怎么来的,所以在这里整理一次。
首先,一个大前提,以下porter/duff公式是针对预乘(premultiplied)后的结果的。什么是预乘?假设一个像素点,用RGBA四个分量来表示,记做(R,G,B,A),那预乘后的像素就是(R*A,G*A,B*A, A),这里A的取值范围是[0,1]。所以,预乘就是每个颜色分量都与该像素的alpha分量预先相乘。可以发现,对于一个没有透明度,或者说透明度为1的像素来说,预乘不预乘结果都是一样的。
为什么要用预乘方式来表示像素?主要是这样会使公式更简单。而且实际上,在实际运算过程中,使用预乘像素进行运算在某些情况下效率会更高。但预乘会对运算精度有一定影响。关于预乘的种种内容,这里不讨论,有兴趣可以自行研究。
开始讨论porter/duff混合公式之前,先定义几个符号
C - 表示像素的颜色,即(RGBA)的RGB部分,C是color的缩写
A - 表示像素的透明度,A即alpha
s - 表示两个混合像素的源像素,s即source
d - 表示两个混合像素的目标像素,d即destination
r - 表示两个像素混合后的结果,r即result
F - 表示作用于C或A上的因子,F即factor
有了这个符号之后,可以开始用它们来描述porter/duff混合公式了,如下,
Cr = Cs*Fs + Cd*Fd
Ar = As*Fs + Ad*Fd
对于12种不同的混合方式,仅仅是Fs与Fd的取值不同,比如最为常见的SRC_OVER混合方式,
Fs = 1, Fd = (1-As)
所以
Cr = Cs + Cd*(1-As)
Ar = As + Ad*(1-Ad)
我们之前提到的Src*alpha + Dst*(1-alpha)其实就是SRC_OVER的一种特殊情况,即目标像素的alpha为1的情况。你可能决定这两个公式长得还有点区别,别忘了porter/duff公式是以预乘方式来讨论的,展开成非预乘之后就是
Cr = Cs*As + Cd*Ad*(1-As)
如果Ad = 1,那就和之前的公式一样了。对于通常的GUI应用,因为最终的背景一定是alpha为1的,所以使用这个公式就足够了。但是,对于OSD与video叠加的情况,由于OSD的最终背景很可能是半透明的,如果再使用这个简化过的公式,可能就会造成结果不正确了。这种时候 就必须按照porter/duff公式严格计算。
下面是12种porter/duff混合的具体定义,
1. CLEAR
Fs = Fd = 0
2. SRC
Fs = 1 Fd = 0
3. DST
Fs = 0 Fd = 1
4. SRC OVER
Fs = 1 Fd = (1-As)
5. DST OVER
Fs = (1-Ad) Fd = 1
6. SRC IN
Fs = Ad Fd = 0
7. DST IN
Fs = 0 Fd = As
8. SRC OUT
Fs = (1-Ad) Fd = 0
9. DST OUT
Fs = 0 Fd = (1-As)
10.SRC ATOP
Fs = Ad Fd = (1-As)
11.DST ATOP
Fs = (1-Ad) Fd = As
12.XOR
Fs = (1-Ad) Fd = (1-As)
其实除了第1和第12条,其它都是两两相对的,很好理解。
以上是关于图形混合概念的主要内容,如果未能解决你的问题,请参考以下文章