Photoshop中的混合模式公式详解

图层混合简介

在这里插入图片描述

图层混合(blend)顾名思义,就是把两个图层混合成一个。
最基本的混合是alpha融合(alpha compositing),这是一个遵循光的反射与透射等(简化版)物理学原理的混合方式。
各个图像处理软件中,往往还提供很多具有一定艺术风格的混合方法,这是本文的主要讨论内容。但须注意,为了更深入地理解混合模式,alpha融合是必需要掌握的前提知识。

为了更好地理解本文内容,我们做如下约定:

  • 所有色彩是归一化的,也就是值域在[0, 1]之间(而非[0, 255]),否则不仅公式不容易写,而且还不适配hdr的情况。
  • 一般情况下,混合都是逐像素,大部分时候甚至逐通道计算。(在Photoshop中,仅有深色浅色不是逐通道计算)
  • 部分混合模式满足交换律,即交换两个图层的上下位置,结果不变。
  • 一些混合模式的结果要求截断到[0, 1]之间,否则会发生不可预测的结果,这些混合模式仅能作用于int类型的数值;还有一些则不要求,这些则能作用于float类型的数值,其结果可以越过[0, 1]范围。

Photoshop中的混合模式

在这里插入图片描述
截止2022版本,Photoshop中有27个混合模式,分为六大类,各类别以及包含的混合模式为:

  • 正常类别:正常,溶解
  • 变暗类别:变暗,正片叠底,颜色加深,线性加深,深色
  • 变亮类别:变亮,滤色,颜色减淡,线性减淡(添加),浅色
  • 复杂类别:叠加,柔光,强光,亮光,线性光,点光,实色混合
  • 差异类别:差值,排除,减去,划分
  • HSL类别:色相,饱和度,颜色,明度

除了溶解(Dissolve)模式以外,其他的混合都有明确的公式,溶解靠随机数实现,随着透明度降低,有越来越多的随机像素点的alpha通道会变成0,这样就会随机地显示出下方图层,表现得好像溶解了一样。本文主要讲有公式的那些混合模式,溶解不在此列,所以这里简单描述一下,后面就不再提了。

为了全面理解混合模式的公式,需要首先从RGB出发(即alpha通道恒等于1),在了解了RGB的混合之后,要基于此知识进一步推导RGBA的混合公式,也就是含透明度信息情况下的公式,真正写程序时候一般使用RGBA的公式即可,因为RGBA涵盖了RGB的情况。

部分混合模式在RGB情况下,交换前景与背景图后效果相同,此类混合模式有:
变暗,正片叠底,线性加深,深色,变亮,滤色,线性减淡(添加),浅色,差值,排除,实色混合

公式符号约定

fg:foreground,表示前景,即处于上方的图层
bg:background,表示背景,即处于下方的图层
f g c fg_c fgc:表示前景的rgb部分,其中脚标_c是color的意思。背景的脚标含义同理,下面不再赘述。
f g α fg_\alpha fgα:表示前景的透明通道
f g c α fg_{c\alpha} fgcα:表示前景rgb与alpha通道相乘的结果,即alpha预乘。

在写代码时,还需注意除法的问题:所有的除法必需要考虑避免除以0的情况,因此碰到除法时应做如下保护:
a b = a m a x ( b , e p s ) \frac{a}{b} = \frac{a}{max(b, eps)} ba=max(b,eps)a
接下来的公式中不会赘述这一点,但各位读者写代码时需自行注意。

RGB混合公式

正常(Normal)

仅显示上方图层。
N o r m a l ( f g c , b g c ) = f g c Normal(fg_c,bg_c) = fg_c Normal(fgc,bgc)=fgc

变暗(Darken)

取两图层中数值较小者。
D a r k e n ( f g c , b g c ) = m i n ( f g c , b g c ) Darken(fg_c, bg_c) = min(fg_c, bg_c) Darken(fgc,bgc)=min(fgc,bgc)

正片叠底(Multiply)

上下两图层相乘。
M u l t i p l y ( f g c , b g c ) = f g c ∗ b g c Multiply(fg_c, bg_c) = fg_c * bg_c Multiply(fgc,bgc)=fgcbgc

前景与背景为同一个图片时,等同于如下曲线调节:
https://www.desmos.com/calculator/8blh2zzaqc
在这里插入图片描述

颜色加深(Color Burn)

让背景图层颜色变暗,变暗的程度由前景决定,前景越暗,背景变暗的程度就越强。
C o l o r B u r n ( f g c , b g c ) = { 0 , if:  f g c = = 0 1 − m i n ( 1 − b g c f g c , 1 ) , if:  f g c > 0 ColorBurn(fg_c, bg_c) = \begin{cases} 0, &\text{if: } fg_c == 0 \\[2ex] 1 - min(\frac{1 - bg_c}{fg_c}, 1), &\text {if: } fg_c>0 \end{cases} ColorBurn(fgc,bgc)= 0,1min(fgc1bgc,1),if: fgc==0if: fgc>0

前景与背景为同一个图片时,等同于如下曲线调节:
https://www.desmos.com/calculator/5xdaojgl3p
在这里插入图片描述

线性加深(Linear Burn)

前景与背景相加后减1。效果类似颜色加深,只是变暗的曲线是线性的。

L i n e a r B u r n ( f g c , b g c ) = m a x ( f g c + b g c − 1 , 0 ) LinearBurn(fg_c, bg_c) =max(fg_c+bg_c-1, 0) LinearBurn(fgc,bgc)=max(fgc+bgc1,0)

前景与背景为同一个图片时,等同于如下曲线调节:
https://www.desmos.com/calculator/akmwl8cert
在这里插入图片描述

深色(Darker Color)

计算上下两通道的灰度值,谁的灰度值小,结果颜色就取相应图层的rgb颜色。
注意该模式是少有的非逐通道计算的混合模式。该模式不产生fg和bg以外的新的颜色。

变亮(Lighten)

取两图层中数值较大者。

L i g h t e n ( f g c , b g c ) = m a x ( f g c , b g c ) Lighten(fg_c, bg_c)=max(fg_c,bg_c) Lighten(fgc,bgc)=max(fgc,bgc)

滤色(Screen)

滤色是模拟光的反射与透射原理设计的混合模式。如果光照到图片后,我们把反射回来的记为我们看到的图像本身,那么透射过去的就是(1-image),也可以称之为负片,光透过两个图层以后的负片就是(1-fg)(1-bg),对这个结果整体再来个负片,就是滤色的效果。光透过多个图层后一定是越来越暗的,所以最终再做一个整体的负片,就一定是变亮的,并且根据物理原理(或更简单一些,可以根据公式),如果各个输入图层在[0, 1]之间,那么结果就一定也在[0, 1]之间,不会产生数值截断,这是一个非常好的特性。

滤色是非常重要的一种混合模式,是各类发光效果最最常用的混合模式(bloom、glow等)。
S c r e e n ( f g c , b g c ) = 1 − ( 1 − f g c ) ∗ ( 1 − b g c ) Screen(fg_c,bg_c)=1-(1-fg_c)*(1-bg_c) Screen(fgc,bgc)=1(1fgc)(1bgc)

前景与背景为同一个图片时,等同于如下曲线调节:
https://www.desmos.com/calculator/sa04opay5a
在这里插入图片描述

颜色减淡(Color Dodge)

让背景图层颜色变亮,变亮的程度由前景决定,前景越亮,背景变亮的程度就越强。

C o l o r D o d g e ( f g c , b g c ) = { 1 , if:  f g c = = 1 m i n ( b g c 1 − f g c , 1 ) , otherwise ColorDodge(fg_c, bg_c) = \begin{cases} 1, &\text{if: } fg_c == 1 \\[2ex] min(\frac{bg_c}{1-fg_c}, 1), &\text {otherwise} \end{cases} ColorDodge(fgc,bgc)= 1,min

上一篇:Matlab实现粒子群优化算法(PSO)求解路径规划问题


下一篇:[笔记] ffmpeg docker编译环境搭建-常见问题