1.1 RGB模式,ARGB模式及其运算
1.1.1 RGB模式及其运算
RGB是色光三原色(Red红,Green绿,Blue蓝)的简写,物理学上,自然界的所有颜色都可以分解为这三种色光。不同的颜色,色光的值会有所差别。反过来,任何颜色都可以通过红绿蓝三种色光合成出来。白色把任何色光都反射出来了,所以它的红绿蓝成分都等于100%,黑色不反射任何色光,三原色的成分都等于0%。红色只反射红光,所以红色光等于100%,另外两种色光值为0%。
计算机软件习惯将色光称作“通道”,并将该概念扩展到其它的色彩模式中。同时,计算机为每个色彩通道分配一个8位的存储空间,每个通道的取值范围为0~255(0代表0%,255代表100%)。红绿蓝三个通道混合为一种颜色,在内存就要占用24位的空间,即3个字节。
要解释颜色值和通道之间的关系,二进制运算总是在所难免,这对于学习美术但是没有计算机编程基础的朋友而言,无疑是件很头疼的事,要深入剖析,恐怕得开一章书来论述。所以,如果接下来的内容您阅读起来觉得困难,建议您找一本介绍计算机基础知识的书来进行同步阅读。
在Flash CS6里,在确保有fla文档打开的情况下,点击菜单项“窗口”-“颜色”(Alt+Shift+F9),就会弹出如图 1.1 的颜色面板。
给面板上方的下拉框选择了“纯色”一项后,下方就会出现一个调色板,用户可以通过拖动左侧的圆圈,中间的滑块直接选取颜色,也可以通过修改右侧或者下方的文本框来直接设置颜色的值。
本节讲的是RGB/ARGB模式,所以我们先把焦点集中在红色标注的区域上。右下方的R,G,B,A分别代表红,绿,蓝和不透明度四个通道。这里我们暂时忽略A的部分。
左下方的数值,对于未接触过颜色计算的朋友而言,乍一看似乎跟右侧的值完全扯不上关系。实际上这个关系就大了。左下方数值的6个字符,每两个就对应右侧的一个通道,在图1.1中,C4代表R(红)的值,196,85代表G(绿)的值,133,EE代表B(蓝)的值,238。
图 1.1 Flash CS6的调色工具
我们可以写一段小代码测试一下:
1 trace(parseInt("C4",16)); 2 trace(parseInt("85",16)); 3 trace(parseInt("EE",16)); 4 trace(Number(196).toString(16)); 5 trace(Number(133).toString(16)); 6 trace(Number(238).toString(16));
测试结果为:
196,133,238,C4,85,EE
很显然,左侧的颜色值就是个16进制形式的数字,把字符两两取出来各自转成10进制以后,就刚好等于右侧的RGB数值。那么,C485EE它算是个啥?是简单拼接的字符串?还是具有真正意义的16进制数?
下面来看看0~15之间的整数,它们的2进制,10进制和16进制的写法分别如下:
10进制 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
2进制 |
0 |
1 |
10 |
11 |
100 |
101 |
110 |
111 |
16进制 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
10进制 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
2进制 |
1000 |
1001 |
1010 |
1011 |
1100 |
1101 |
1110 |
1111 |
16进制 |
8 |
9 |
A |
B |
C |
D |
E |
F |
不难看出,16进制里面显示的1个“位”(字符)恰好代表了2进制的4个位,所以,代表蓝色的EE占了8个位,而代表绿的85和代表红的C4也分别占据了8个位,其中,85要左移8位,而C4则要左移16位,于是16进制数0xC485EE可以由R,G,B三个值通过二进制位运算得出:
1 0xC485EE = 0xC4 << 16 | 0x85 << 8 | 0xEE
AS3的颜色值一般以0xC485EE这样的16进制数表示,所以,颜色值的计算公式如下:
1 color = red << 16 | green << 8 | blue。
反之,如果要从color值取得各个通道的成分:
1 0xEE = 0xC485EE & 0xFF 2 0x85 = 0xC485 & 0xFF = (0xC485EE >> 8) & 0xFF 3 0xC4 = 0xC485EE >> 16 & 0xFF
于是有
1 blue = color & 0xFF 2 green = (color >> 8) & 0xFF 3 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模式。
ActionScript3游戏中的图像编程(连载四)