处理窄带图像,可选颜色可以说是最方便使用的工具。但是PS只能应用8bit的调整,导致多次调整以后像素颜色分离很严重。于是就想办法把算法分离出来,考虑另外开发一个能在32位浮点下计算的小程序。
首先,可选颜色的调整选项包括所谓的“可选的”[颜色]与“可调的”[青色][洋红][黄色][黑色]。显然,这四个颜色是油墨印刷下的基础色,CMYK。调整黑色是调整颜色的整体亮度,这个在窄带处理中一般不会去动它,这里只考虑CMY的影响。
再回到[颜色]的选项,会发现总共有9个选项,后面那三个也是涉及整体亮度的调整,同样不去管它,只考虑前面六个。红黄绿青蓝紫,均分了整个色轮。
那么计算一个像素在一个可选颜色调整下会发生什么变化,首先要判定这个像素属于什么色相,或者说它会受到什么颜色的影响,如果随便调都会影响到所有像素的话,那“可选”就无从谈起。判断的方法很简单,考察像素的RGB值,它必然会受到值最大的那个分量的影响。其次,它会受到最大值与第二大值形成的颜色的影响,下面以8bit下的颜色举例。
(R,G,B)=(128,84,64),最大值为R,其次为G,那么会受到红色(R)和黄色(R+G)的影响,它在色轮上处于红色线和黄色线之间;
(R,G,B)=(128,64,64),最大值为R,B=G,那么它只受到红色的影响,它在色轮上刚好落在红色线上。
确定了一个调整会影响哪些像素之后,就得知道是怎么影响。第一步是确定调整的范围大小,即某个通道的最大值与最小值的差。如果[颜色]选择红绿蓝中的一个,那么范围大小为三通道最大值减中间值;如果选择黄青紫中的一个,范围大小则是中间值减最小值,即:
if (Red||Green||Blue) delta=max(R,G,B)-mid(R,G,B);
if (Yellow||Cyan||Magenta) delta=mid(R,G,B)-min(R,G,B);
为了简化,后文简写为max和mid。
选好[颜色]之后,我们有青色、洋红、黄色三个选项可以调整。这三个颜色分别是RGB的补色,因此增加青色就是减少红色,诸如此类。
那么对于RGB任意通道,在[颜色]选红绿蓝时,将青色+100%,会导致R通道变化为:
①Rmin=(255-max+mid)×R/255
由于增加青色等于减少红色,此时的R为最小值,记为Rmin。那么根据上述的调整范围大小,可知青色-100%的情况下,R通道变化为:
②Rmax=Rmin+delta
如果调整量非±100%,也很简单,假设调整强度为Amount,其值有符号:
③R'=R-delta×Amount
如果调整其他通道,例如调整黄色,由于黄色是蓝色的补色,上面三个式子只需要将R改写成B即可:
①Bmin=(255-max+mid)×B/255
②Bmax=Bmin+delta
③B'=B-delta×Amount
当[颜色]选黄青紫时,情况也很相似,只是把①中的max和mid改成mid和min:
①Rmin=(255-mid+min)×R/255
②Rmax=Rmin+delta
③R'=R-delta×Amount
这样就描述了所有的情况。
需要注意的是,这样的调整下,Amount值在不到±100%时调整就会到达极限。举个例子:
(R,G,B)=(89,104,46),显然这会受到[黄色]和[绿色]的影响。我们选择[绿色],并且调整青色,可以计算得到:
delta=104-89=15
Rmin=(255-104+89)×89/255=84
Rmax=84+15=99
那么很显然,当Amount分别等于-67%和+33%时,R'就已经达到极值,超出这个范围,调整Amount的话,像素值也就停留在极值不变化。
此外,范围大小取决于max-mid或者mid-min,因此当像素三通道特别接近,即像素颜色接近中性灰时,可调范围就特别特别小。也就是说,如何剧烈的可选颜色调整,都不会让本就是中性灰的像素偏离中性灰。
参考: