[ActionScript 3.0] flash中的颜色

在 Flash 中,颜色就是一串特殊的数字,一个颜色值可以是0到16,777,215中的任意数值,这就是24位(bit)色彩。也许大家会问,为什么有16,777,216(256*256*256)种颜色值,因为 Flash 使用 RGB 颜色值,意味着每个颜色都可以由红(red),绿(green),蓝(blue)三种颜色构成。这三种合成色的每一种都是一个从0到255中的数,所以,对于每个红黄蓝都有256种可能的深度,结果会有约1,678万种颜色。

这个系统之所以叫做24位颜色是因为要使用8位(0或1)才能表示256个数值。8位乘以3(红,黄,蓝)意味着需要24位才能表示1678万种颜色值。我们马上还要学到32位色系统,它有额外的8位数值表示透明度(alpha)。很难想像一个值为11,273,634的颜色是什么样的。因此,开发人员通常采用另一种数值表示系统:十六进制。如果大家在 HTML 中使用过颜色,那么这对于你来说并不会陌生,但不管怎样还是让我们来学习一下这些基础知识吧。

使用十六进制表示颜色值

       十六进制(Hexadecimal,简写 hex),以16为基础,每位数都是0到15中的任意一个数,而十进制则是以10为基础,每位数都是0到9中的任意一个数。由于没有可以表示10到15的数,所以要借用字母表的前六个字母,A到F,来表示它们。这样,每个16进制数都可以是0到F中的一个(在 Flash 中,十六进制数不区分大小写,使用A到F或a到f均可)。在 HTML 中使用16进制数,要加上 # 作为前缀加以标识。与其它语言一样,在 ActionScript 中,使用0x作为前缀。比如,十六进制的 0xA 与十进制的10相等,0xF等于15,0x10等于16。在十进制中,每一位都是它右边一位数的十倍,如243表示为2的100倍,4的10倍,3的1倍。在十六进制中,每一位都是它右边一位数的十六倍,如0x2B3表示为2的256倍,B(或11)的16倍,3的1倍。        对于24位来说,就等于0xFFFFFF,此外,这6个十六进制数可以分为三部分。第一部分代表红色,第二部分代表绿色,最后两位表示蓝色,被象征性地记为0xRRGGBB。        记住每一个合成色都可以为0至255(十六进制表示:0x00到0xFF)中的值。因此,红色可以表示为 0xFF0000,表示纯红色,因为它的绿色为0,蓝色为0。同样,0x0000FF表示纯蓝色。

       拿11,273,634为例,将它转换为十六进制(稍后为大家介绍一种简单的方法),结果为 0xAC05A2,可以把它分解为 red(红色) = AC,green(绿色) = 05,blue(蓝色) = A2。可以看出red(红色)和blue(蓝色)的值比较高,而绿色几乎没有,我们就可以猜到这个颜色大概为紫色,这是在十进制数中看不出来的。请注意,在 ActionScript 中,使用哪种进制表示都可以,在一个函数中使用颜色值既可使用十进制又可使用十六进制。对于 Flash 来说,11,273,634 和 0xAC05A2 是一个数,只是对于可怜的人类来说后面一种表示法更易读懂。那么如何在两种进制之间进行转换呢,将十六进制转换为十进制非常容易。只要输出这个十六进制数就可以了,trace 函数会自动将它转换为十进制。 trace(0xAC05A2); 将十进制转换为十六进制要用到 toString(16)函数,如: trace((11273634).toString(16));

输出结果为ac05a2,如果要使用这个数,不要忘记加上0x。

透明度和32位色

       前面提到过,除了24位色以外,还有32位色,多出8位用于表示透明度。就像角度制与弧度制一样(第三章内容),AS 3 在24和32位色的使用上有些混杂。AS 3 的绘图 API 很大程度上是基于 Flash MX(Flash 6) 建立的,总之,绘图 API 函数使用一个特殊的参数来指定透明度,所以还要延用24位色。另外, BitmapData 类,是从 Flash  8 才加入的,并且使用的是32位色彩。如果大家对某个函数使用哪种色彩体系有疑问的话,请查看 ActionScript 参考手册。

       我们可以使用十六进制以 0xRRGGBB 这样的格式来表示一个色彩值。同样,32位的颜色也是如此,以 0xAARRGGBB 这样的格式来表示,其中 AA 表示透明度。因此,0xFFFFFFFF 就表示不透明的白色,0x00FFFFFF 表示完全透明的白色,而0x80FFFFFF 表示近似 50%透明度的白色。

新的数值类型:int 和 uint

       在以前的 ActionScript 版本中,只有一种数值类型 Number,它可以表示正整数,负整数或是浮点数(或0)。我们已经习惯了这种自由的用法,但是现在多增加的两种数值类型可以让我们的代码更加清晰。

       第一个新增加的数值类型是 int(整型),这个类型可以为正整数或负整数或零。如果我们把一个浮点数值声明为 int 类型的话,小数部分会自动被去掉。比如,把 1.9 声明为 int,结果为 1。因此,当我们确定只使用整数时,就把变量声明为 int ,在循环中用于计数的变量一般应该是 int 。下面这段代码中,i变量永远不会得到浮点数值,这时使用int类型就有了意义。

for(var i:int = 0; i < 100; i++) { // do something in here! }

       第二个新的类型是 uint(无符号整型),“无符号”意思是没有正负(+-)号,永远为正数。32位颜色值在 AS 3 中总是以 uint 类型存储,这是因为无符号整型比(有符号)整型能够保留更多的数值。 int 和 uint 都可以存储32位数,这个数值大于40亿,但是 int 有一个特殊位用于存储符号(+-),所以只有31位数(大于20亿),这样就可以标记正数或负数了。所以,使用int 类型声明一个正的32位色彩值就显得太大了!如果用了又会怎样?让我们来试试:

var color1:int = 0xffffffff; trace(color1);//-1 var color2:uint = 0xffffffff; trace(color2);//4294967295

0xFFFFFFFF 的值相当于十进制的 4,294,967,295,因为这个值对于 int 来说太大了,所以结果被“反转”了过来变成了 -1!当然这不是我们所期望的结果。如果使用 uint 类型的话,就没问题了。因此,由于色彩值永远都是正数,并有可能超出 int 的值域范围,所以要使用 uint 来存储它们。

色彩合成

        如何将红、绿、蓝三种颜色值组成一个有效的颜色值,这是个普遍的问题。假设有三个变量 red,green,blue,每个变量里面保存一个0到255之间的数。下面是这个公式: color24 = red<<16 | green<<8 | blue; 加入透明度后,建立一个32位色彩值,公式如下: color32 = alpha << 24 | red << 16 | green << 8 | blue;

这里用到了两个位操作符,大家以前可能没有接触过。位操作是对二进制(0或1)进行的操作,对于24位色来说,如果把颜色值的每一位都列出来,就会得到一串由24个0或1组成的字串。把十六进制 0xRRGGBB 分解成二进制后是这样的:

RRRRRRRRGGGGGGGGBBBBBBBB,我们看到有8位red,8位green,8位blue,也就是说8位二进制数等于256。

在色彩合成公式中,第一个位操作符是 << ,是一个按位左移操作符,该操作是将二进制数值向左侧移动。比如,红色值(red)为0xFF或255,可以由二进制表示为: 11111111 将它向左移动16位,结果是: 111111110000000000000000 在24位色彩中,它表示红色,转换为十六进制后为 0xFF0000,是纯红色。 下面,假设有一个绿色值(green)为 0x55(十进制85),二进制表示为: 01010101 将它向左移动8位后,结果为: 000000000101010100000000 这样一来,这8位数完全移动到了绿色值的范围。

最后,假设一个蓝色值为0xF3(十进制243),二进制表示为:11110011。因为它们都处在蓝色(blue)的范围,所以不需要再去移动它。这样我们总共就拥有了三组数: 111111110000000000000000 000000000101010100000000 000000000000000011110011 可以简单地将它们加起来,成为一个24位数,但是,还有一种更好更快的方法:使用或(OR)运算,符号是 | 。它会将两组数的每个二进制位进行比较,如果两个之中有一个数为1,那么结果就为1,如果两个数都为0,那么结果就为0。可以使用或(OR)运算将 red,green,blue 的值相加起来,也可以这么说“如果这两个数或这两个数中有一个数等于1,那么结果就为1”。最终结果为: 111111110101010111110011 将这个数转换为十六进制就等于 0xFF55F3 。当然,我们无法看到这些二进制位,也不会与这些0或1打交道,只需要学会这种写法: var color24:Number = 0xFF << 16 | 0x55 << 8 | 0xF3; 十进制写法是: var color24:Number = 255 << 16 | 85 << 8 | 243; Flash 并不关心人们使用的是十进制数还是十六进制数。

同样,还可以将 red,green,blue 的值全部转换为十六进制的字符串,然后将它们连接成一条很长的字符串,最后再把它们转换为十六进制数。但是,如果这样做的话会很麻烦,而且使用字符串操作会非常慢。相反,使用二进制操作是 ActionScript 中最快的运算,因为它们属于低级运算。

       对于32位数,其实道理也是一样的,加入8位 alpha(透明度)通道并将其向左移24位。例如,有一组32位数为0xFFFF55F3,将 alpha 值向左移动24位,结果如下: 11111111111111110101010111110011 前8位数表示透明度,后面的 red,green,blue 值与前面的一样。

获取颜色值

假如有这样一个数 0xFF55F3,要从中提取 red,green,blue 的值。下面请看公式,首先是24位色彩: red = color24 >> 16; green = color24 >> 8 & 0xFF; blue = color24 & 0xFF;

一句句来看。首先,大家也许会猜到 >> 是按位右移运算符,用于将二进制位向右移动。如果这些位向右移动得过多,那么这些数字就会消失,就没有数了。 下面从 red 开始: 111111110101010111110011 将颜色值向右移动16位,结果如下: 11111111,或是0xFF(255) 对于 green,向右移动8位,结果如下: 1111111101010101

这里已经得出了 blue 的值,但是 red 值还留在一旁。这里就是要使用与(And)操作符的地方,与(OR)操作符相同,都是对两组数值的比较,可以这样解释“两个数相比较,如果两个都是1那么结果就为1,如果其中有一个为0,那么结果就为0”。我们把它与0xFF进行比较: 1111111101010101 0000000011111111

因为所有的 red 位的数字都与0相比较,所以它们的结果均为0,只有当两个数都为1时结果才为 1,所以结果如下: 0000000001010101

对于 blue 则不需要执行右移操作,只需要让它和 0xFF 执行与(AND)操作即可。对于32位色彩,方法也是相同的,只不过需要一点小小的改动: alpha = color32 >> 24; red = color32 >> 16 & 0xFF; green = color32 >> 8 & 0xFF; blue = color32 & 0xFF;

这里,获取 alpha 的值需要向右移动24位。

例如:

var c:uint=0x23fff3; trace((c>>16).toString(16));//获取red值23 trace((c>>8&0xff).toString(16));//获取green值ff trace((c&0xff).toString(16))//获取blue值f3

posted on 2015-06-19 17:03  晏过留痕  阅读(981)  评论(0编辑  收藏  举报