11RIA 闪客社区 - 最赞 Animate Flash 论坛

搜索
查看: 1888|回复: 0
上一主题 下一主题

[高级教程] 【9RIA—沐枫】—【基础小知识】第4节(Flash 中的颜色)

[复制链接] TA的其它主题
发表于 2018-2-6 17:28:54 | 显示全部楼层 |阅读模式

【游客模式】——注册会员,加入11RIA 闪客社区吧!一起见证Flash的再次辉煌……

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
转载:9RIA游戏开发者社区(天地会)
作者:沐枫(原天地会大神)


【基础小知识】系列教程(总目录)——沐枫大神出品


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 是一个数,只是对于可怜的人类来说后面一种表示法更易读懂。

那么如何在两种进制之间进行转换呢,将十六进制转换为十进制非常容易。只要输出这53个十六进制数就可以了,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++) {
// 在这儿做些事情!
}

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

var color1:int = 0xffffffff;

trace(color1);

var color2:uint = 0xffffffff;

trace(color2);

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 位。

———————————————————————————摘录自《动画教程》



下载:
Flash 中的颜色.rar (7.78 KB, 下载次数: 7)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条

感谢所有支持论坛的朋友:下面展示最新的5位赞助和充值的朋友……更多赞助和充值朋友的信息,请查看:永远的感谢名单

SGlW(66139)、 anghuo(841)、 whdsyes(255)、 longxia(60904)、 囫囵吞澡(58054)

下面展示总排行榜的前3名(T1-T3)和今年排行榜的前3名的朋友(C1-C3)……更多信息,请查看:总排行榜今年排行榜

T1. fhqu1462(969)、 T2. lwlpluto(14232)、 T3. 1367926921(962)  |  C1. anghuo(147)、 C2. fdisker(27945)、 C3. 囫囵吞澡(58054)



快速回复 返回顶部 返回列表