1.3 图片是如何用数字来记录的
除了文字以外,人类表达信息的另外一个重要手段就是图案。图画对比文字,更能在不同语言、不同种族间的人们之间传递信息。
1.3.1 如何在屏幕上显示“A”
我们使用的计算机,即便是最简单的“命令行”模式,实际上都是软件“画”出来的图案。如果没有图形能力,计算机就会是下图1-13所示的这种样子:
图1-13 纸孔带
看到那两个程序员在盯着穿孔纸带看吗?感觉是不是很“杯具”?所以即便是我们认为已经很普通很简单的字符界面,背后也有一套完整的图形数字化机制在运作的。我们已经知道了字符A在ASCII编码表中的代表数字是65,那么计算机对于要把65这个数字“画”到屏幕上,还需要做什么工作?
最基本的就是要找到字符A的图形数据,也就是要知道如何用一系列的黑色像素点,在白色的背景上,拼出A的形状。我们可以放大一下,看看屏幕上的A实际上是怎么样的一个图形,如下图1-14所示。
图1-14 图形A
这个图形,可以用一个11行8列的格子阵列来容纳,然后对于白色的格子用0表示,对于黑色的格子则用1表示。因此这个字符就可以按行分成11个数字的序列,而每个序列则从左到右的排列内容:
0 00 1 0 0 0 0
0 00 1 0 0 0 0
0 00 1 1 0 0 0
0 01 0 1 0 0 0
0 01 0 1 0 0 0
0 01 0 0 1 0 0
0 01 1 1 1 0 0
0 10 0 0 1 0 0
0 10 0 0 0 1 0
0 10 0 0 0 1 0
1 10 0 0 1 1 1
如果我们把数字排成一排,这将会是一个这样的序列:
000100000001000000011000001010000010100000100100001111000100010001000010010000111000111
虽然我们用肉眼看起来非常的晕,但是计算机却可以很轻松的处理这么长一串数字,它只需要按每8个数字一行的规则,把黑色或者白色的点画在屏幕上就可以了。除了A这个字符外,所有需要显示的字符,实际上都需要有类似上面的这串数字,作为描绘字符到屏幕上的数据的。这样一批代表字符“图形”的数字,往往被打包到一块,成为“点阵字库”。
同样的一个字符,可以具备多个不同的字体,只要我们用不同的点阵字库来负责“描绘”,就能得到不同的字体的显示,所以我们现在看到的,在屏幕上或者打印机打印出来的字符,都是由各种各样的点阵字库所控制的。
把要显示的图形,划分成很多小格子,然后对每个格子里面的内容用数字编码,然后把这些数字都串起来,是计算机记录图形最基本的方法。
1.3.2 绚烂的画面变成冗长的数字
对于仅仅有黑白两色的字符,可以用0和1的序列就可以完整的表达,但是如果是彩色的图案呢?其实方法也是非常类似的,我们可以看看下面这个例子,这是一个如下图1-15所示的老虎头。
图1-15 老虎头
如果我们把这个图形放大,就可以用一系列小方格来“近似”的描绘出这个图形,如下图1-16所示。
图1-16 放大后的老虎头
这个时候,我们只需要用点阵字库的方法,同样为每个点使用一个数字,来表示这个点的颜色,就可以了。当然因为我们用的是彩色图形,所以只用0和1是不足够的,对于颜色比较简单的图画,我们用0~4096之间的数字来表可能出现的颜色,应该就足够了,具体的的编码规则其实很简单,就是把所有的颜色,先分解成红、绿、蓝“三原色”,然后根据这三种颜色的深浅程度各自分为255个等级,用255以内的数字来表示,这样一个颜色就会是“红色等级”“绿色等级”“蓝色等级”这样三个数字,这三个数字的最大值都是255,放到一起相乘,就会是16777215,也就是说每个点实际上可以显示166777215种颜色(实际上人眼很难辨认出166777215种颜色中的全部颜色)。这个是不是和ASCII编码表有点类似呢?是的,这只是一种为了用数字表示颜色而做的编码表。通过这个编码表,就可以把这个图案完全数字化成为一串由166777215以内的数字,所拼接起来的数字序列。
显然如果我们每个点都用166777215这么大的一个数字来表示,一幅图片将会要用很长很长的一串数字来表示。而从这副图片看,这里面大多数的数字都会是相同的,因此我们可以用一种叫“调色板”的方法,来大大的减少表示这幅图案的数字长度:
首先我们把这份图片里面用到的颜色都先抽取出来:比如黑色、白色、绿色、浅黄色、三种棕色、三种红色。然后我们用0-9为这10种颜色编号,并且把表示这10种颜色的数字,都先串起来,这样我们就得到了10个166777215以内的数字——这10个数字就是这幅图片的调色板,包含了这幅图案的所有颜色信息。最后我们把代表整福图案的数字,全部都用“调色板”中颜色所对应的编号来代替,这样整个图案就会变成一串0-9之间的数字的序列,这串数字就大大的缩短了。最后我们把“调色板”和点阵图的数字拼到一起保存,就得到了最终图像的数据。如果需要显示这串数字所代表的图案,只需要先读出“调色板”,然后再读出每个点的数字,去“调色板”那里查找一下,获得最终的颜色数据,根据这个颜色数据去显示对应的颜色(这环节显示卡的驱动程序会完成),就能还原这幅图案了。
上面所说的显示彩色图形的方法,其实只是显示黑白字符的一种扩展,都是用“点阵”作为基础的描述方式的方法,这种方法有一个专用的名字叫“位图”。然而除了位图方式来表达图形,还有另外一种叫“矢量图”的方式。矢量图不去把图形分割成很多个小格子来描述,而是把图形中的线条都描述成函数曲线,然后记录这些代表这些函数的数字,来表达图形。这种方法的好处是图片无论如何放大,都一定不会失真,因为函数曲线不会因为放大而变化,缺点就是,如果要把图片用函数来编码,需要很复杂的计算,所以现实和保持这些图片比较耗费CPU的运算时间。互联网上流行的FLASH图画,很多就是用矢量图方式来制作的。
1.4 其他的信息是如何用数字来记录的
前面我们探讨了如何用数字来表示文字和图形,这两种不同的信息的数字化方法中,其实是有一些共同点的:
以上三个共通的做法,除了用来表达文字和图形,同样也可以用来表达很多其他的信息,比如声音,我们可以把声音按时间分解成单元,然后对每个单位时间里的声音,按照其频率和音量编码。最后把一个声音变成一串以频率、音量所编码的数字。对于动画,也可以按时间分解成一帧帧的画面,每幅画面再以数字编码,这样由多组表示画面的数字所串接的序列,就可以用来表示动画了,GIF格式的动画就是用这种方式记录的。如果你要记录的是类似电话本之类的数据,则一样是先把电话本的条目先分解,然后再把每个条目分解成“名字”、“电话号码”两个部分,最后以文字编码表来编码“名字”和“电话号码”,最后把这些编码后的数字一起串接起来,形成一个完整的电话本。
任何的信息,只要有办法进行分解,编码,就能变成数字放到计算机里处理。所以现代的计算机几乎可以处理任何我们能接触到的信息。而指挥计算机去“解码”(把数字变成信息)和“编码”(把信息变成数字)的方法,正是计算机软件最常见的工作。
1.5 贻害甚广的“二进制文件”
我们时常会这样形容一个文件:“这是一个文本文件,这是一个图片文件,这是一个Word文件……”,但是当我们无法说出一个文件的类型的时候,我们就会说:“这是一个二进制文件”,然而,这个说法有几个严重的概念错误,从而阻碍了我们对于解决文件格式所能做出的反应:
希望我们在了解了计算机如何用数字来表达信息之后,我们能够理解计算机中各种文件格式的含义,而不会再被各种“格式”的说法弄的头晕脑胀。——一切都是数字,用数字表达的信息。
感谢大家的阅读,如觉得此文对你有那么一丁点的作用,麻烦动动手指转发或分享至朋友圈。如有不同意见,欢迎后台留言探讨。