本节书摘来自异步社区《点睛:ActionScript3.0游戏互动编程》一书中的第1章,第1.1节,作者:游志德 , 彭文波 更多章节内容可以访问云栖社区“异步社区”公众号查看。
第1章 趣解色彩—江南美景与艺术编程
唐代著名诗人白居易的《忆江南》一诗中,一句“日出江花红胜火,春来江水绿如蓝”就把苏杭一带秀丽明艳的的江南风光描绘得细致传神,从科学的角度看,其精华之处就在于诗人仅以红绿蓝3种颜色,就把蓝天白云下花红水绿的景观刻画得淋漓尽致。
本诗用词浅显易懂,诗句朗朗上口,因此被多次收录到各地的小学语文教材中作为基础的写景诗进行讲解。同理,我们也将以诗中所提到的红、绿、蓝3种颜色开启本书的艺术编程之旅。
1.1 RGB模式、ARGB模式及其运算
1.1.1 RGB模式及其运算
R、G、B是色光三原色(Red红、Green绿,Blue蓝)的简写,物理学上,自然界的所有颜色都可以分解为这3种色光。不同的颜色,色光的值会有所差别。反过来,任何颜色都可以通过红、绿、蓝三种色光合成出来。白色把任何色光都反射出来了,所以它的红、绿、蓝成分都等于100%、黑色不反射任何色光,三原色的成分都等于0%;红色只反射红光,所以红色光等于100%,另外两种色光值为0%。
计算机软件习惯将色光称作“通道”,并将该概念扩展到其他的色彩模式中。同时,计算机为每个色彩通道分配一个8位的存储空间(在某些场合同,具体位数还跟显示设置有关,但本书不对此作展开讨论),每个通道的取值范围为0~255(0代表0%,255代表100%)。红、绿、蓝3个通道混合为一种颜色,在内存就要占用24位的空间,即3个字节。
要解释颜色值和通道之间的关系,二进制运算总是在所难免,这对于学习美术但是没有计算机编程基础的朋友而言,无疑是件很头疼的事,要深入剖析,恐怕要花一章的篇幅来论述。所以,如果接下来的内容大家阅读起来觉得困难,那建议您找一本介绍计算机基础知识的书来进行同步阅读。
Flash CS 5.5里,在确保有文档打开并且选项卡定位在fla/xfl文件标签的情况下,我们选择菜单项【窗口】|【颜色】(Alt+Shift+F9),就会弹出如图1-1的颜色面板。
我们给面板上方的下拉列表框选择了“纯色”一项后,下方就会出现一个调色板。用户可以通过拖动左侧的圆圈以及中间的滑块来选取颜色,也可以通过右侧或下方的文本框直接输入或调整颜色的值。
本节讲的是RGB/ARGB模式,所以我们先把焦点集中在红色标注的区域上。右下方的R、G、B、A分别代表红、绿、蓝和不透明度4个通道。此处暂时忽略A部分。
左下方的数值,乍一看似乎跟右侧的RGB值完全扯不上关系。但实际上,两者的关系相当密切。左下方数值的6个字符,每两个就对应右侧的一个通道。图1-1所示Flash CS 5.5的调色工具中,C4代表R(红)通道值196,85代表G(绿)通道值133,EE代表B(蓝)通道值238。
我们可以写一小段代码测试一下。
代码清单1-1
trace(parseInt("C4",16));
trace(parseInt("85",16));
trace(parseInt("EE",16));
trace(Number(196).toString(16));
trace(Number(133).toString(16));
trace(Number(238).toString(16));
测试结果如下所示。
196,133,238,C4,85,EE
很显然,左侧的颜色值就是个16进制形式的数字,把字符两两取出来各自转成10进制以后,就刚好等于右侧的RGB数值。那么,C485EE是什么呢?是简单拼接的字符串还是具有真正意义的16进制数呢?
下面我们来看看0~15的整数,它们的2进制、10进制和16进制写法分别如下。
不难看出,16进制里面显示的1个“位”(字符)恰好代表了2进制的4个位,所以,代表蓝色的EE占了8个位,而代表绿的85和代表红的C4也分别占据了8个位,其中,85要左移8位,而C4则要左移16位,于是16进制数0xC485EE可以通过对R、G、B3个值进行二进制位运算得出以下结果。
0xC485EE = 0xC4 << 16 | 0x85 << 8 | 0xEE
AS3的颜色值一般以0xC485EE这样的十六进制数表示,所以,颜色值的计算公式如下。
color = red << 16 | green << 8 | blue
反之,如果要从color值取得各个通道的成分,那么运算过程可表示如下。
0xEE = 0xC485EE & 0xFF
0x85 = 0xC485 & 0xFF = (0xC485EE >> 8) & 0xFF
0xC4 = 0xC485EE >> 16 & 0xFF
于是有以下结果。
blue = color & 0xFF
green = (color >> 8) & 0xFF
red = (color >> 16) & 0xFF
如果您认为我说得还不够明白,就可以阅读《ActionScript 3.0动画教程》一书的“第4章:渲染技术”中关于颜色方面的介绍,Keith Peter在RGB颜色运算这个要点上的讲解比我要详细得多。
RGB模式通过三原色光的成分确定一种颜色,每个通道的值代表它对应的色光所反射的比例。假如R=127(0x7F),则代表这种颜色反射了50%的红光,所以,0x7F0000所呈现的就是一种亮度中等的红色。
至于同时反射多种光会得到什么样的颜色,那就是物理学家所钻研的问题了。对于我这种光学白痴而言,在这问题上可谓十窍通了九窍—— 一窍不通,比如,为什么把红光和绿光全反射出来(0xFFFF00)会得到黄色,我没办法站在科学的角度上给出一个合理的解释。
美术人员往往不用关注这些,他们只要打开调色板,就可以随心所欲地抽取自己喜欢的颜色(当然他们所做的事情没我想象中那么简单,少点审美细胞,我想大家在那儿点个老半天都不可能调出让自己满意的色彩来)。
而像我这种没有美术功底、物理又学得一般的程序员,通常情况下很难判断出RGB模式的数字(一些很特征性的数值如0x000000/0xFFFFFF等除外)代表我们感官认知里的哪种颜色(如褐色、紫色、橙色等)。正因这种学术性太强的模式不够直观,诸如HSB那样更为感性的色彩模式便应运而生,我们将在1.2节提到它。但不管大家使用何种模式,在AS3里,最终都得转换成RGB模式才可以运用到显示对象上。
下面我们开始介绍ARGB模式。
**
1.1.2 Flash中的ARGB模式与不透明度的关系**
ARGB是Flash、SVG等矢量处理软件特有的一种色彩模式,事实上我觉得它有点不可思议,A(alpha)不应该作为一个通道存在于色彩模式中,它更适合作为一个独立的属性从色彩模式中抽离出来并应用到其他的色彩模式(如HSB、CMYK、LAB等)中。Alpha之所以被Flash定义为通道,个人认为有3个原因。
1)Flash并非专业的图形软件,将它与RGB一视同仁,可以帮助AS3程序员更方便地使用颜色,实践证明,易用性确实比单独抽离出来要高。
2)AS3只有RGB这一种内置的色彩模式,加上去可让开发者感觉到颜色的功能不会过于单一。但Photoshop那样的软件就免了,搞完ARGB,还得弄AHSB、ACMYK、ALAB之类,模式的数量一下子就翻倍了,给模式的切换带来各种不便,同时也体现出了结构僵硬、不易扩展等缺点。在Photoshop里,我们可以粗略地把蒙板理解为alpha通道。
3)颜色在AS3里面以uint的形式存在,它可以包含32位数值,RGB各占了8位以后,刚好剩下8位给A通道使用。
虽然在Flash IDE里调色板显示的A范围为0%~100%,但是,在ARGB模式中,A的取值范围也调整为0~255。假设上面所说的颜色(0xC485EE)带上了50%的不透明度,那么,它的A=255 * 0.5= 127 = 0x7F,所以ARGB数值就等于0x7FC485EE。同理,不透明度为100%时,ARGB值等于0xFFC485EE;不透明度为0%时,ARGB值等于0x00C485EE。
32位的ARGB色彩很少直接应用在显示对象上。对于DisplayObject来说,它们依然通过一个独立的alpha属性来控制不透明度。ARGB更多的是在BitmapData上做事,这里我们暂不展开讨论。
此外,由于通道的易用性和可控性较强,所以Photoshop也没有完全放弃掉 alpha通道,我们依然可以在【通道】面板的三角菜单中找到【新建通道】的菜单项。