zoukankan      html  css  js  c++  java
  • [computer graphics]透明颜色混合(Color Blending)

    颜色混合(Color Blending)

    颜色混合是通过混合两种颜色,来得到第三种颜色的一种方法。已有的颜色一般称为(destination),将要放上的颜色称为(source)。一般图片除了颜色的RGB通道,还有一个alpha通道来表示透明度。我们可以利用混合来制作半透明的效果。有两种混合方式,传统的(直接)混合和预乘(Premultiplied Alpha)混合。

    直接混合

    假设颜色值为(C_s),透明度为(a_s)的颜色要混合到颜色(C_d)上,那么混合后的颜色通过以下公式计算。

    [C_o = a_sC_s+(1-a_s)C_d ]

    例如60%透明度的红色渲染到白色背景上:

    [C_o =(255,0,0)*0.6+(255,255,255)*(1-0.6)=(255,102,102) ]

    Premultiplied Alpha 混合

    Premultiplied Alpha混合需要将alpha通道的值乘到(r,g,b)上,(ar,ag,ab,a),如果是60%透明度的红色,则表示为(153,0,0,0.6)。
    如果用Premultiplied Alpha模式混合,那么混合的公式变为

    [C_o = C_s^{'}+(1-a_s)C_d ]

    因为(C_s)已经乘了透明度了。

    两种混合的差别

    假设需要将一个2x1像素的图片缩放到1x1,那么用线性插值方法。这里假定左边的颜色值为(255,0,0,1),右边的值为(0,255,0,0.1),直接混合的结果

    [((255,0,0,1)+(0,255,0,0.1))*0.5=(127,127,0,0.55) ]

    Premultiplied Alpha混合的结果

    [((255,0,0,1)+(0,25,0,0.1))*0.5=(127,255,0,0.55) ]

    直接混合的太绿,Premultiplied Alpha符合直觉。这是为什么呢,其实也很简单,在插值的时候红色和绿色被同等考虑,然后alpha在混合以后,也无法知道原来颜色的透明度,所以绿色权重过大。而Premultiplied Alpha相当于提前给绿色一个权重然后再去混合,比较符合直觉。

    解决的问题

    Premultiplied Alpha可以解决边缘溢出的问题,因为在采样(插值)的时候,边缘部分的像素值的差距还是挺大,直接混合模式会出现问题。

    参考

  • 相关阅读:
    try catch finally return
    github结合TortoiseGit使用sshkey,无需输入账号和密码
    github上fork别人的代码之后,如何保持和原作者同步的更新
    第9章 浅度和深度复制
    9.7结构类型
    excel在msdn上的说明文档
    9.6接口和抽象类
    [LeetCode]N-Queens II
    鸟哥Linux私房菜知识汇总8至9章
    Memcahce(MC)系列(三)Memcached它PHP转让
  • 原文地址:https://www.cnblogs.com/WAoyu/p/13162007.html
Copyright © 2011-2022 走看看