《点睛:ActionScript3.0游戏互动编程》——1.4 浅析亮度与灰度/明度的关系

本节书摘来自异步社区《点睛:ActionScript3.0游戏互动编程》一书中的第1章,第1.4节,作者:游志德 , 彭文波 更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.4 浅析亮度与灰度/明度的关系

进入正题之前,我们先来了解一下灰度/明度。

1.4.1 灰度/明度的概念及其与HSB亮度的异同
在很多场合,灰度与明度的概念完全等价。

“灰度”一词最初来源于摄影领域,在彩色显像技术问世以前,拍摄出来都是黑白照片,只有黑白灰3种颜色能完好无损地记录下来,其他颜色将根据其亮度呈现出不同深度的灰色。亮度越大灰色越浅,反之越深,把从黑到白的过渡区域划分为若干个级别,就会得到不同的“灰度等级”。能呈现的灰度等级愈多,画面的层次感就愈丰富。

所以,从彩色转黑白,就可以简单理解为去除色调并且把饱和度调整为0的过程。

从概念上看,灰度与亮度所表达的是同一个意思。那么,我们可以给两个术语直接划上等号吗?

为了更直观地分析以上问题,我制作了如图1-29的一幅图片。


《点睛:ActionScript3.0游戏互动编程》——1.4 浅析亮度与灰度/明度的关系

这可不是某国家的三色旗,我们只是简单地绘制了6个色块,上面3种颜色分别为#FF0000,#00FF00和#0000FF,即一个通道是255,另外两个通道是0;下面3种颜色恰好相反,两个通道是255,一个通道是0,即#FFFF00,#FF00FF和#00FFFF。

我们尝试把这张图片转成黑白照。如果灰度与亮度等价,那么我们只需把这6种颜色的饱和度都设置为0就好了。

首先看看HSV,根据转换公式,只要RGB其中一项达到最大值,亮度就是100%。所以,我们把S都设置为0以后,6种颜色都变成白色了。很显然V跟灰度在数理层面上的描述大相径庭,任何一种彩色都不可能在黑白照片里呈现为白色。

至于HSL,它的亮度=(min+max)/2,以上6种颜色,min均为0,max均为255,所以计算结果均为50%,灰度值跟白色是拉开距离了,但肉眼往往告诉我们,下面一排的颜色看着要刺眼一些,转成黑白照之后,下面的颜色应比上面的浅。

1.4.2 灰度的计算方法
我们回过头来看RGB,站在科学的角度来解释,它们确实也有更明亮的理由,因为下面一排颜色反射出来的色光总量是上一排色的两倍。

为此,笔者曾自作聪明地发明了一条“原创”的灰度公式。

Gray=(r+g+b)/3

哈哈,用色光总量来表达颜色的灰度想必就比较准确了吧!沾沾自喜一番以后,我还试着用这条自创的定律来转换这张测试图片。上下色块的灰度果然拉开了,可是很不幸地,左右相邻、边界分明的色块依然粘连在一块,如图1-30所示。


《点睛:ActionScript3.0游戏互动编程》——1.4 浅析亮度与灰度/明度的关系

显然此法生成的黑白照难登大雅之堂,色块之间的分界线全部丢失,而且同一行的颜色在我们人类的视觉系统里,亮度也不尽相同。比如视网膜会认为上排的绿色要比旁边的红和蓝明亮一些,而下排的粉红色则没有相邻的黄色与淡绿来得刺眼。

一项伟大的发明——灰度心理学公式诞生了!它汇聚了光学物理、眼球视光学、人类心理学、美术鉴赏等前沿学科之精华,集科技、艺术、社会科学于一身,高深莫测,唯美唯妙,堪称视觉科学史上最惊天地、泣鬼神之大作,没有之一。

灰度心理学公式并不复杂,它深入浅出地描述了各种颜色对肉眼刺激程度的差异,仅仅使用最简单的加法和乘法就完成了灰度的整个演算过程:

Gray = r0.299 + g0.587 + b*0.114

式中,r、g、b的取值范围均为0~1。

如果大家有阅读过fl.motion.AdjustColor类的代码,想必就会对这条公式有一种似曾相识的感觉。AdjustColor里用到了公式里的3个系数(具体数值可能有一些微小的差异),而实际上,AdjustColor正是用灰度代替了亮度。至于为什么,我们看看上面的黑白照转换结果就不言而喻了。

令r=g=b=1,灰度就刚好等于100%,所以它实质上是对RGB 3个数值做了一个加权平均数的运算,其中g的权重(通俗点说叫比重)最大,红色次之,蓝色最小。因此,心理学公式认为,绿色最刺眼,它比红色要明亮1倍,反射一点绿光对视网膜的刺激相当于两点红光。

以上描述与肉眼的感知相当接近,但至于具体数值是如何测算出来的,我们就无从考究了。

笔者尝试运用灰度心理学公式对图1-29进行灰度转换,效果要比自己的“原创”定律有水平多了,如图1-31所示。


《点睛:ActionScript3.0游戏互动编程》——1.4 浅析亮度与灰度/明度的关系

至此,亮度跟灰度的关系已经比较明确了,它们都为量化色彩的明暗而生,本着“科技以人为本”的精神推动着人类社会精神文明的进步,其中,亮度着重对整体的把握,从颜色类别、鲜艳程度、明暗程度3个人类感知属性去描述被数理科学抽象过的色彩数值,而灰度则更强调对事物单项属性的深度探讨,有针对性地弥补HSB模式中亮度计算方法与视觉器官不够吻合的缺陷。

现在大概也不会有人去拍摄黑白照片了(纯粹抱着怀旧心态的除外),即使遇到真正需要使用黑白图像的场合(例如纪实片的录制与后期处理、汶川地震哀悼日播放的视频等),也不会专程从博物馆借用一台19世纪出厂的黑白相机来开展拍摄工作,而都通过Photoshop等软件对彩色图像进行去色处理。而灰度转换的算法,恰恰就来源于上述的心理学公式。

在艺术编程领域,灰度除了直接用来制作黑白效果(比如游戏按钮的禁用状态、玩家复活前的灰屏效果等)以外,还广泛应用于图像识别、色彩调整、边缘检测、光影预处理、模型上色等图像处理技术中(Photoshop的颜色混合模式就是一个成功的典范)。它的专一性使图形的创作流程有章可循,让艺术不再只掌握在专业设计师的手上。

下面我们就借助灰度公式搭配出一套相对和谐的色系。
**
1.4.3 用灰度/明度指导色彩搭配**
我们试着只通过调整不等于0的通道,让上一排的色彩在灰度上保持一致,把3个颜色分别代入到心理学公式,得

Gray(red) = r * 0.299
Gray(green) = g * 0.587
Gray(blue) = b * 0.114

让它们灰度相等,则

r * 0.299 = g * 0.587 = b * 0.114

可见,b值一定最大,不妨让b取最大值255,求得r=97,g=50。把这两个值分别应用到红和绿两个色块上。

绿色不再显得刺眼,整体感也因为灰度的一致性而变得比之前柔和了,如图1-32所示。


《点睛:ActionScript3.0游戏互动编程》——1.4 浅析亮度与灰度/明度的关系

以上算法的局限性也显而易见,灰度永远无法冲破 0.114这一关口,因为此时最暗的蓝色已经达到255这个上限,导致颜色的整体亮度不能超过11.4%,明色系无法搭配出来。想要突破这一瓶颈,我们就不得不尝试给多个通道同时赋值了。

现在假设要将灰度等级调整为跟绿色(#00FF00)一致,用心理学公式算得Gray=0.576 * 255 = 147。即对于R和B,都有

R * 0.299 + G * 0.587 + B * 0.114 = 147

因为红色和蓝色都比绿色要暗,所以不妨让红色的R和蓝色的B都等于最大值255。

于是对红色而言,有2550.299 + G 0.587 + B * 0.114 = 147,简化得

G * 0.587 + B * 0.114 = 71

一条方程,两个未知数,无法求出唯一解。在HSB模型里,H是我们需要拉开差距的值,而B已经为灰度所替代,所以只能试图从S下手多加一条方程了。

无论是HSV还是HSL,饱和度的公式都有一个共同特征:max和min的差值越大,饱和度就越高。因为#00FF00的饱和度达到了满值,而max已经让R通道据为已有,所以G和B就只能去占min的位置了。

令min=0,色彩的饱和度即达到最大值。

我们先试着让G=0,则有B 0.114 = 71,求得B = 623,数值彻底溢出了,无奈之下,只能让B=0,此时G 0.587 = 71,求得G = 121。

我们用同样的方法处理蓝色,得到蓝色的RGB数值为(0,201,255)。

我们把颜色值应用到色块上,明色系搭配出来啦,而且也蛮好看,如图1-33所示(当然这只是按笔者自己的审美标准来评价)。


《点睛:ActionScript3.0游戏互动编程》——1.4 浅析亮度与灰度/明度的关系

同理我们尝试在不改红色的前提下搭配出一套中等明度的色系,就会发现,在要求饱和度达到满值的情况下,总要有一项的数值大于255 才能使灰度的计算结果跟红色保持一致,色系搭配失败。这也从一定程度上解释了为什么一个色彩鲜艳而丰富的界面里很少会出现大面积的纯红色(GCD类型的网站除外)。

另外,根据色相环的构成,如果想让色调更加均匀,那选择三色系的时候,就最好对美学色环进行等分,比如取0,120,240这样的3个色相,搭配为红黄蓝三色,以达到对比的和谐统一,如图1-34所示。


《点睛:ActionScript3.0游戏互动编程》——1.4 浅析亮度与灰度/明度的关系

灰度的另一个任务是给灰度图上色或者是彩图换色(实质上也是取了彩图的灰度之后再重新上色),但考虑到要用比较复杂的代码来实现,我们就先搁置一下。

上一篇:从零开始学_JavaScript_系列(25)——dojo(10)摧毁一个widget


下一篇:django 1.8 官方文档翻译:13-1-2 使用Django认证系统