1.4 编码与解码的概念
我们都知道计算机底层采用的是二进制码,即计算机底层存储的全都是0和1,不管是我们看到的视频、图片、音乐、文档和其他任何存储在电脑上的文件,其底层都是0,1,那么为什么要采用0和1来进行存储呢?这些0和1在计算机底层又是如何存储的呢?0和1又是如何变成我们需要的文件呢?
1.4.1 CPU的计算
我们知道计算机底层都是靠CPU来进行运算的,CPU的发展经历了如下几个过程,如图所示:
也就是说CPU最原先是通过二极管发展而来,我们可以把这些二极管看做是一个一个的开关,这些开关只有两个状态:通(1)、断(0),那么1个二极管能够表示几种状态呢?很明显就两种,0和1。
2个二极管可表示4个状态:
00,01,10,11
3个二极管可表示8个状态:
000,001,010,011,100,101,110,111
4个二极管就可表示16个状态,5个表示32个状态,6表示64个状态…一个CPU拥有的晶体管越多,电流在一个时间单位上流动的分支越多,从宏观上讲,可以在CPU上处理的数据越多,机器就越快。目前CPU都集成了超大规模的集成电路,多大呢?早在2012年Intel发布的Core i7处理器的芯片集成度达到了14亿个晶体管,数据计算能力可想而知。
就简单而言,这些晶体管就是微型的电子开关,它们是构建CPU的基石。当计算机从内存中读取到指令后(0、1),将其转换为电信号,1则表示高电频,0则表示低电频,通过一些与门,或门,与或门等逻辑控制电路。而计算机内部有超大规模的集成电路,也就可以接受非常庞大规模的数据进行计算,把处理好的数据通过同样的方式将这些信号进行转换写进内存、然后再写出磁盘、麦克风、显示器等外部设备。
Tips:计算机相关的硬件设备(以及各项电子设备)的工作原理涉及到电路、模拟信号、数字信号、计算机组成原理等诸多计算机/电子信息等专业课程,不在本书研究范围内,大家有兴趣可以自行查看相关书籍的内容来了解这部分知识。到目前为止,我们只需要大致了解到CPU内部是一块超大规模的集成电路板(虽然远不止这么简单),并且能进行计算即可。
那么计算机中存储的二进制是如何转变为我们看到的内容呢?
这中间就存在一个编码与解码的过程,其实我们在计算机中打开任何的一个文件、应用程序、游戏等其实都可以看做是一个解码的过程,只不过对应的解析器不同罢了。
1.4.2 文本的编码与解码
以最普通的文本为例,我们跟计算机双方约定好当在键盘上输入一个字母A时,保存到电脑上的内容就为0100 0001,当我们在电脑上输入一个字母B时,电脑底层存储的就是0100 0010,越来越多的信息需要通过编码存储到计算机内,因此编码表这个概念就出来了,世界上的一些权威组织就开始着手于编码的制作,有了编码表我们就能够使用0和1来代表世间上的万物了。编码表就相当于一个翻译官,充当人类与计算机之间的一个翻译官。
当我们打开计算机中的记事本输入内容后保存到文件时,过程如图所示:
当我们打开计算机中的记事本查看文件中的内容时,过程如图所示:
市面上有非常多的编码表,每个表码表的编码内容以及规则是不一样的,因此我们存储到计算机时采用的编码表应该与我们取出数据解码时的编码表一致。
目前计算机中用得最广泛的字符集及其编码,是由美国国家标准局(ANSI)制定的ASCII码(American Standard Code for Information Interchange,美国标准信息交换码),它已被国际标准化组织(ISO)定为国际标准,称为ISO 646标准。适用于所有拉丁文字字母,ASCII码有7位码和8位码两种形式。
- 标准ASCII码:标准ASCII码也叫基础ASCII码,使用7位二进制数来表示所有的大写和小写字母,数字0到9、标点符号,以及在美式英语中使用的特殊控制字符等。7位可以表示128种状态,每种状态都唯一地编为一个7位的二进制码,对应一个字符(或控制码),这些码可以排列成一个十进制序号0~127,所以在7位二进制码种,最多可以表示128个字符。
- 扩展ASCII码:扩展ASCII 字符是从128到255(0x80-0xff)的字符。许多基于x86的系统都支持使用扩展ASCII。它将每个字符的第8位用于确定附加的128个特殊符号字符、外来语字母和图形符号。针对扩展的ASCII码,不同的国家有不同的字符集,所以它并不是国际标准。
ASCII第一次以规范标准的型态发表是在1967年,最后一次更新则是在1986年,至今为止共定义了128个字符(标准ASCII码),当初的设计并没有考虑欧洲那些扩展的拉丁字母,也没有考虑韩语和日语和中文汉字等。因此各个国家开始着手制定自己的字符编码,例如 ISO/IEC 8859(欧洲字符集)、shift_Jis(日语字符集)、GBK(中文字符集)等。
一般的外国人用的数字和字母有限,根据ASCII表来编码,1个字节可以表示完全。我们中国人大部分用的是汉字,所以引入了GB2312编码表,国标(6000多个汉字),一个汉字用2个字节表示。随后又扩展了GBK,扩展编码,能够达到几万个汉字。例如在ASCII编码表中,“65(十进制)”代表字母“A”,在GBK编码表中“CED2(十六进制)”代表中文汉字“我”。
下表是标准ASCII编码表中规范的部分字符内容:
二进制 | 十进制 | 字符 |
---|---|---|
0100 0001 | 65 | A |
0100 0010 | 66 | B |
0100 0011 | 67 | C |
0100 0100 | 68 | D |
0100 0101 | 69 | E |
0100 0110 | 70 | F |
0100 0111 | 71 | G |
下表是GBK编码表中规范的部分字符内容:
二进制 | 十六进制 | 字符 |
---|---|---|
10110100 11110011 | B4F3 | 大 |
10111100 11010010 | BCD2 | 家 |
10111010 11000011 | BAC3 | 好 |
1.4.3 图片的编码与解码
了解完二进制是如何转成文本后,我们接着学习二进制是如何转成图片的,学习二进制是如何转成图片之前我们必须了解一些前置知识。
1. 三原色
人眼对红、绿、蓝最为敏感,人的眼睛像一个三色接收器的体系,绝大多数的颜色可以通过红、绿、蓝三色按照不同的比例合成产生。同样,绝大多数单色光也可以分解成红、绿、蓝三种色光,这是色度学的最基本的原理,也称三原色原理(以上介绍摘抄与百度百科)。
在计算机中可以使用十六进制表示法来表示一种颜色(取值范围为00~FF
),如:#FFFFFF
;其中前两位表示红色数组,中间两位表示绿色数值,最后两位表示蓝色数值。或10进制表示法,如:RGB(255,255,255),取值范围为0~255
,颜色数值依次为(红,绿,蓝),值越大表示颜色程度越深。
Tips:十六进制表示法需要在前面加上“#”,例如:
#FF0000
。
大多数的一些软件或网站在设置颜色时都会提供如图所示的颜色调色板,每一个十进制的颜色数值都会对应一个十六进制的颜色数值:
常用的颜色如表所示:
十六进制颜色代码 | 十进制颜色代码 | 颜色 |
---|---|---|
#FF0000 | RGB(255,0,0) | 红色 |
#00FF00 | RGB(0,255,0) | 绿水 |
#0000FF | RGB(0,0,255) | 蓝色 |
#FFFFFF | RGB(255,255,255) | 白色 |
#000000 | RGB(0,0,0) | 黑色 |
#00FFFF | RGB(0,255,255) | 青色 |
#FF00FF | RGB(255,0,255) | 紫色 |
#FFFF00 | RGB(255,255,0) | 黄色 |
通过数值的调整,我们可以调整出自然界中绝大多数的颜色。将颜色的十六进制或者十进制转换为二进制后,就是这个颜色在计算机中底层存储的形式。
例如:白色十六进制是#FFFFFF,将其转换成二进制是11111111 11111111 11111111。红色十六进制是#FF0000,转换后是11111111 00000000 00000000。绿色十六进制是#00FF00,转换后是00000000 11111111 00000000。
2. 分辨率
分辨率:图像处理和显示技术中,分辨率通常指图像的清晰度,即图像中可以分辨的最小细节。一张图片是由若干个像素点组成的,分辨率决定了这些像素点的排列以及数量,如图所示。
以一张1920×1080分辨率的图片为例,其横向排列1920个像素点,纵向排列1080个像素点,每一个像素点都是有三原色混合而成的一种特定颜色,这些颜色可以转成对应的二进制码存储在计算机中,像素点以特定的方式排列在指定的位置,就组成了一张完整的图片。
图片由大量的像素点组成,每个像素要用到24位比特(3个字节),那么一张1920×1080的图片大小为1920×1080×3=6,220,800字节≈6MB,占用的空间非常大。因此图片会有各种压缩算法,在尽量保证不失真的情况下把体积压到最小,常见的JPG、PNG等就是常见的图片压缩算法。像素的比特信息经特定算法压缩,就形成了特定格式的图片。
1.4.4 视频的编码与解码
在学习二进制是如何转换成视频之前我们必须了解一些前置知识。
- FPS(Frames Per Second):即每秒传输帧数,视频的本质是一帧一帧的图片切换带来的动画效果,意思是显卡一秒钟能显示多少个画面。一般来说人眼能接受的最低连贯画面是一秒钟24帧,而要达到流畅的程度,那么一秒钟起码要出现30帧才行。
- Hz(hertz):中文名为赫兹,这个参数出现在显示器时,代表一秒钟内画面能够刷新的次数。我们常见的显示器一般都是60Hz,代表该显示器一秒可以刷新60次画面。
视频画面是否流程,需要FPS和Hz共同的提升。如果显卡帧率输出有60FPS,使用的是120Hz的显示器,这时,我们就会感到画面卡顿,因为显示器每秒可以显示120张画面,而帧率只有60FPS,那么显示器就会造成卡顿现象,如果帧率有120FPS,显示器只支持60HZ,那么这120的帧率也只是浪费,增加了显卡的功耗而已,却并没有改善游戏画质,因为显示器只能显示60张每秒。
但就目前的计算机而言,显卡的输出帧数能力都比较强悍,瓶颈大多都在显示器的刷新率上,所以一般情况下只要解决了显示器的刷新率问题,那么用户整体的体验感就会得到提升。
假设当前显示器的频率为60hz,显卡的输出帧数也是60帧,并且视频的分辨率为1920×1080,假设不使用任何压缩算法,每秒钟输出60张1920×1080的图片(约6MB),就得计算60*6MB≈360MB的数据。而当今主流的游戏笔记本的屏幕刷新率都能达到144hz、240hz,甚至有的都能达到360hz。计算的数据量非常庞大,因此我们要对其进行编码进行数据压缩,以此来降低数据传输和存储的成本,常见的mp4、avi等就是属于视频的编码格式(压缩方式)。需要注意的是,无论如何视频的渲染尤其是高分辨高帧数的视频对CPU以及显卡的计算能力要求都是非常高的。
1.4.5 音频的编码与解码
二进制转换音频的过程也叫音频数字化,其过程较为复杂,是模拟声音信号转变为数字信号再由数字信号转换为模拟信号的一个技术实现,其过程涉及到声音的采集,转换为模拟信号,采样、量化等。了解音频数字化之前我们先了解一些关于声音的一些前置知识,
1. 声波
我们知道声音是以声波的形式在空气中传播的,声波是声音的物理表现形式,它是由物体振动产生的能量传播方式。当物体振动时,它会激发周围介质(如空气、液体或固体)中的分子或原子振动,这些振动随后以波的形式传播开来。
一段声波中包含有声音的频率、振幅、音色等声音元素,通过声波我们可以将声音这一抽象概念通过数据的形式表现出来。声波的采集就是原声音的采集,通过麦克风、话筒等录音设备就可以采集到一段声音的声波。
例如我们通过声波来反映一段声音的频率、振幅、音色等信息。
(1)通过声波的频率反映声音音调,频率低音调低,频率高音调高。
(2)通过声波的振幅反映声音响度,振幅大响度大,振幅小响度小。
(3)通过声波的规律性反映声音音色,一般来说具有规律性的声波听起来悦耳,反之为噪音。
2. 模拟信号
当录音设备采集到声波数据后将会以电信号的方式模拟出声波信号,声波被电信号模拟出来的信号就是声音模拟信号,这种模拟信号是对声波的一种电子化表示,以便在音响设备中再现出类似原始声波的效果。
模拟信号是连续变化的,模拟信号的最大特点是随着时间连续变化的值,它可以包含无限数量的可能幅度值。
我们可以把模拟信号模拟声波的过程看作是汽车的仪表盘模拟汽车行驶速度的过程,当驾驶员深踩一脚油门时,汽车会迅速提高行驶速度,然而汽车仪表盘的数据并不是从0km/h直接变成80km/h,虽然这个变化的时间很短,但也是从0km/h连续变化到80km/h,期间汽车仪表盘指针肯定指向过10、11.7、12.785、20.491、38.4、69.8、78等这样的数据。同理,当声波的频率忽高忽低,振幅忽大忽小时模拟信号也会随着时间连续不间断的模拟出声波频率的高低以及振幅的大小。
例如汽车行驶速度的通过仪表盘来模拟,如图所示。
通过观察曲线图我们可以看到,取任意一个时间点都可以获取到这个时间点所对应的速度值,通过声音模拟信号模拟声波的变化也类似于这样。如图所示,当通过模拟信号将声波信息模拟出来后,取任意一个时间点所对应的声波幅度数值也能取出来,这就是模拟信号的最大特点——随着时间连续变化的值。
类似于模拟信号的变化还有水银温度计的变化,当我们把水银温度计放置在10°的水温环境下时突然加了一些温水进去,使得水温一下子骤升至50°,然而水银温度计的数值肯定经过了20°、32.7°、39.1°、45.8°等数值,并不是从10°直接变成到50°,而是随着时间的变化温度上数值从10°增加至50°(虽然这个时间可能非常短)。
3. 数字信号
数字信号是模拟信号的数字化,它是一系列离散的电脉冲(信号),可以利用其某一瞬间的状态来表示具体的数据。数字信号与模拟信号最大的不同点在于模拟信号是随着时间连续变化的值,它可以去任意时间点上的数据。而数字信号则是离散的数值,即取某几个瞬间的状态来表示具体的数据,数字信号包含的是有限数量的可能幅度值。
如图所示,数字信号来模拟声波时,只有某个具体的时间点才会有对应的声波数据,而不是和模拟信号那样任意的时间点上都能查询到对应的声波数据。
数字信号只有某几个时间点上才能有对应的数据,这些时间点并不是连续的,这意味着某些时间上的数据会缺失,将数字信号的这些时间点连接起来可以大致还原模拟信号。
如果将模拟信号看着是汽车上的仪表盘、水银温度计,那么数字信号就可以看做是电动车上面的数字仪表盘和电子温度枪。
不管是数字仪表盘还是电子温度枪,这些设备的数值和时间都是离散的。以电动车的数字仪表盘举例,例如我们骑电动车时突然深拧加速,假设速度从0提速到了40km/h,那么电子仪表盘上的速度很有可能就从10km/h变化到25km/h再变化到34km/h,最后变化到40km/h,在电子仪表盘模拟电动车行驶速度的变化时,只显示了(模拟了)25、34、40这些数值,而25~34
以及34~40
之间的数据都不会被显示(模拟)。
那为什么有了模拟信号还要转换为数字信号呢?因为数字信号相对比模拟信号存在有很多优点,如下:
(1)数字信号抗干扰性强:数字信号在传输和处理过程中可以通过纠错码等技术来提高抗干扰能力,相比之下,模拟信号在传输和处理过程中容易受到噪声和干扰的影响,导致信号失真或丢失。
(2)数字信号的可编程性:数字信号可以通过编程进行处理和操作,例如滤波、压缩、加密等,这使得数字信号在处理和存储方面更加灵活和方便。
(3)数字信号的可复制性:数字信号可以通过复制和传输进行无损的复制和传递,而模拟信号在复制和传输过程中可能会产生失真或损失。
(4)数字信号便于存储和传输:数字信号以二进制数的形式表示,便于计算机进行存储和传输。同时,数字信号可以进行压缩处理,以节省存储空间和提高传输效率。
(5)数字信号便于加密和解密:数字信号可以通过加密算法进行加密处理,以保护信号的安全性和隐私性。而模拟信号则难以实现加密和解密操作。
数字信号相对模拟具有许多优势,使其在现代通信中占据主导地位。
4. 音频数字化
所谓音频数字化就是把模拟信号如何具体的转换为数字信号,其过程分为采样、量化、编码等。
(1)采样:将连续的模拟声音信号转换为一系列离散的采样点的过程,采样点随后由模拟数字转换器(ADC)转换为数字信号,以便计算机或其他数字设备进行处理、存储、传输和播放。每秒钟对声波幅度值样本的采样次数称为采样频率,单位为HZ,声音的质量受采样频率的影响。
如图所示,在一段模拟信号中,我们对其根据指定时间进行采样,我们可以发现采样的频率越高,与模拟信号越接近,声音还原程度越高,数据量也越大。
(2)量化:将幅度上连续取值(模拟量)的每一个样本转换为离散值(数字量)表示的过程,它实现了在幅度轴上对信号的数字化。通过量化,音频信号被转换为一系列的数字值,这些数字值可以精确地表示原始音频信号的幅度,如图所示。
通过对比不同的量化等级,我们可以发现量化等级越高量化值的精度也越高,更高的量化等级意味着更多的量化值可以用来表示音频样本,就能够更好的还原音频。
计算机底层是以二进制存储的,因此我们需要将量化值转换为二进制。在声音量化过程中,我们使用量化位数来表示量化值所需要的二进制位数,例如在量化等级为4的情况下使用两位二进制数就可以表示量化值,因此它的量化位数就是2bit,量化等级为8的量化位数就是3bit,如图所示。
然而,需要注意的是,量化位数的提高虽然能够提升音质,但也会导致音频文件的数据量增大。因为每个音频样本都需要用更多的二进制位来表示,所以音频文件的存储空间会相应增加。例如,一个16bit的音频文件在数据量上会是8bit音频文件的两倍。
(3)编码
声音通过采样、量化过后就成为了010101的二进制数,编码决定了这些二进制数如何存储,有的编码规则的存储效率非常高,同样一段的音频可以使用非常少的空间将其存储,有的编码规则则更加注重与音频的质量,但可能会花费更多的空间来存储。
不同的编码方式就被分成了不同类型的音频文件类型,常见的音频文件有:
- WAV(Waveform Audio File Format)格式:WAV是一种无损音频格式,音质非常好,因为是无损的,保留了原始音频的所有信息。常用于多媒体开发的中间文件、保存音乐和音效素材。由于WAV是无损压缩,因此文件体积相对较大。
- MP3(MPEG Audio Layer III):MP3是一种有损音频格式,广泛应用于音乐、广播、电视等领域,具有较高的压缩比和较好的音质。音质在128Kbit/s以上表现还不错,但相较于无损格式有所损失。适合需要较小文件体积,且对音质要求不太苛刻的场合,如网络音乐下载、移动设备存储等。
- AAC(Advanced Audio Coding):ACC是一种高压缩比的音频压缩算法,它的压缩比要远超过较老的音频压缩算法,如AC-3、MP3等。适用于需要较高音质,同时文件体积也要相对较小的场合,如在线音乐流媒体、手机铃声等。