GameMaker8.0 新手教程 Part 10 -RGB与HSV-

分类栏目:gamemaker教程

525

GameMaker8.0 新手教程 Part 10 -RGB与HSV-

1、诞生背景

我们知道,计算机的根本是二进制。而二进制是整数的一种表达形式。
换句话来说,计算机本质上只能储存整数。

那怎么行!只能储存整数的计算机还能玩?我们要想办法让计算机储存更多种类的数据!
那么有什么办法呢?有!把所有数据都转化为整数来储存不就行了!

小数怎么保存?那我就先把小数转化为科学计数法,比如:526.41就转换为5.2641x10^2,这样我只要储存两个整数:52461和2就行了。
文本怎么保存?简单!字符和数字一一对应就行了!比如规定A对应65,B对应66,a对应97等,列出一个大大的表,让世界上所有的字符都有与之对应的数字,这样就可以储存任意文本了!

但是,只保存数字和文本还是不够,我们还希望他能储存图像!
在这种背景下,就涌现出了多种将颜色转换为整数数据的转换方案,RGB和HSV就是其中的两种。

2、十六进制

二进制是计算机的根本,但是十分不便于阅读。十进制是人们的日常生活习惯,但是用十进制无法体现计算机计数的特殊性质。因此,十六进制应运而生。
二进制的个位只有0和1,十进制的个位是0~9,而十六进制的个位不仅有0~9,还增加了abcdef(或ABCDEF)六个字母,其中a(或A)表示10,b(或B)表示11,c(或C)表示12,d(或D)表示13,e(或E)表示14,f(或F)表示15。
十六进制转换为十进制的方式就是把第n位乘上16的n-1次幂再相加,如将4dc2转换为十进制就是4*16^3 + 13*16^2 + 12*16^1 + 2*16^0 = 19906
十六进制与二进制的转换十分方便,因为十六进制一位就代表了二进制的四位。例如4dc2,只要把每一位分别转换为四位二进制:4对应0100,d对应1101,c对应1100,2对应0010,再连接起来,0100110111000010就是4dc2的二进制表示方式了。
为什么更多地使用十六进制,而不是更接近十进制的八进制?这是因为,在计算机中,一比特就是一位二进制,但是内存的基本计量单位并不是比特,而是字节(等于八比特),比如一个中文字符占两个字节,一个英文字母占一个字节。两位十六进制刚好能够表示一个字节,这是八进制做不到的,因此十六进制更加适用于计算机中。
两位十六进制的最大值是ff,即十进制的255,这个值也是一个字节所能储存的最大数据。因此,你可以在很多地方接触到255这个数据(通常作为值的上限,如ip地址)。

3、RGB颜色系统

RGB,即红(Red),绿(Green),蓝(Blue)
红绿蓝三色是光的三原色。这三种颜色按不同比例混合,可以得到几乎所有的颜色。
所以,RGB颜色系统,实际上就是把一种颜色用红、绿、蓝三种颜色的强度来表示并且储存。

在传统的RGB颜色系统中,红绿蓝三种颜色通常分为256个强度(0~255),0表示完全没有,255表示最强。只要储存红绿蓝三者的强度,就可以把几乎任何一种颜色保存在计算机中。(一共能储存256×256×256=16777216种颜色)
例如:

(0,0,0)表示黑色。
(255,255,255)表示白色。
(255,0,0)表示红色。
(255,128,0)表示橙色。


在很多语言中,通常都支持用十六进制来表示颜色。(GML请参考第十八章第四节
如:#ff0000(或#FF0000)代表红色,#是颜色说明符(大多数情况下,GML不同),六位十六进制数字中,前两位是red的值,中间两位是green的值,后两位是blue的值。ff是255的十六进制,所以#ff0000表示(255,0,0),即红色。

在GM中,我们可以在图像编辑器里用RGB自定义颜色。(RGU和ESL是源自微软画图工具的说法,实际上几乎不使用这种称呼,他们等效于RGB和HSL)

同样,我们也可以使用函数make_color_rgb(red,green,blue)来自定义颜色,它的返回值可以直接用作各个函数的颜色参数,和GM自带的c_red,c_green等效。

4、HSV颜色系统

HSV系统复杂又难理解,并非一定要掌握。
HSV,即色调(Hue,或译作色相)饱和度(Saturation)亮度(Value,或译作明度)
GameMaker8.0 新手教程 Part 10 -RGB与HSV-
色调(Hue)为角度,在0~360之间,常用的颜色角度如下图:
GameMaker8.0 新手教程 Part 10 -RGB与HSV-
饱和度(Saturation)是指颜色的鲜艳程度,取值范围为0~1,或者说0%~100%,如图:

饱和度为0时,颜色与色调无关,只由亮度决定,亮度为0则是黑色,为1则是白色,之间则是灰色。
亮度(Value)是指颜色的明暗程度,取值范围也是0~1,0就是黑色,1就是纯正的颜色。如图:

在GM8中的特殊性:
在GM中,为了便于储存,将色调、饱和度、亮度的取值范围都放缩到了0~255。
例如:

(任意,任意,0)表示黑色。
(任意,0,255)表示白色。
(0,255,255)表示红色。
(42,255,255)表示黄色。(60*255/360≈42)

在GM有函数make_color_hsv(hue,saturation,value)根据hsv生成颜色。

注意:在GM的图像编辑器中,颜色使用的是HSL而不是HSV。(实际显示的是ESL,但是这种称呼几乎不被使用,E和H是一个意思)
这二者有细微的差别,HSL系统中,L代表Lightness,它比V的范围更广,L取0表示黑色,L取0.5表示纯正的颜色,等效于V取1,而L取1表示纯白色。你可以认为V就是L的一半。
在图像编辑器中,HSL并不是放缩到0~255,而是H为0~239,S和L为0~240,这么做的原因是因为windows自带的画图工具也是这么放缩的。。。所以来一起大喊巨硬萨比吧。

5、RGBA颜色系统与HSVA颜色系统

现在,我们已经能储存所有种类的颜色了,但是这还不够。
有的时候,我们需要一张图片本身是半透明的,甚至这张图片各个地方的透明度还不一样,RGB和HSV就已经无法满足我们了。
RGBA和HSVA,即是在原有的基础之上,再添加了一项新的内容——透明度(Alpha)。
透明度(Alpha)的取值范围为0~1,0表示完全透明,1表示完全不透明,在0~1之间则是半透明。
在GM中,透明度的范围也放缩到了0~255以便于储存。(有特例)

在GM的图像编辑器中,也可以自定义颜色的透明度。

6、后话

除了RGB和HSV之外,还有很多种颜色储存方案,其中常用的还有HSL,YCbCr,CMYK,Lab,Ycc,YUV等等,各自在合适的领域发挥自己的作用。
除了图像以外,其他类型的数据,如音频,视频,软件等,都是以整数的二进制形式储存的,他们都以各种各样的规律把自己和整数对应起来互相转换。
从数据转化到二进制储存(或其他形式,如电子脉冲)的过程叫做编码,反之叫做解码,编码和解码几乎渗透于计算机的方方面面,和计算机打交道,就不可避免需要和编码打交道。
明白了编码的意义,我们就可以去理解一些以前无法理解的东西。
比如,乱码是怎么来的?学了编码之后,我们就可以知道,原来文本都是通过编码转换为二进制储存的,但是,这种转化方式并不唯一,除了最常用的unicode编码,ASCII编码,ANSI编码,shift-JIS编码等也在很多地方被使用,这些编码的区别是,同一个字符对应的数字是不一样的,所以,用某一种编码方式转换为二进制的文本,被另一种编码方式解码,就会被解码成与原本完全不同的文本内容,所以就有了“乱码”的存在。