《图片文件前世今生和衍生技术原理》

前言:计算机存储本质

记住一点,计算机所有的文件均为二进制文件,包括文本文件(它是特殊的二进制文件,为什么特殊?因为它里面全部可直接翻译为字符),这些二进制文件就是一群0101集合(特定软件能打开就能看到),他们的读取与写入,过程完全相同:

读入内存:文件-->二进制流-->-->按格式解码-->应用程序内存数据
写出文件:应用程序内存数据-->按格式编码-->二进制流-->文件

一直以来,我们对于文本文件的处理是比较好理解的,不论是前端的表格还是表单等参数,传到后端的本质都是字符串,所以很好理解,也很好处理。
但对于音频,图像,视频等多媒体文件,我就一直不理解它们的本质。
于是,我详细查询了网上资料,整合成如下几篇完整的《前世今生漫谈》

图片文件前世今生和衍生技术原理
https://www.jianshu.com/p/830202931e59
补档:https://www.jianshu.com/p/3f31b72be674
音频文件前世今生和衍生技术原理
https://www.jianshu.com/p/2f097ab27051
视频文件前世今生和衍生技术原理
https://www.jianshu.com/p/aa78924ee4da

图片文件前世今生及衍生原理漫谈

一、显示器的显示原理

先用一句话总结显示原理:
计算机中的文字和图像都是以像素的形式显示的。显示字符的本质也是显示图像——每一个汉字、英文字符都是以像素的形式在屏幕上输出。
参考博客:

知乎——计算机中的文字和图像是如何显示的?
https://www.zhihu.com/question/296297701

在日常生活中,以像素形式组成图形和文字的不仅仅是计算机,还包括我们经常见到的「十字绣」,做工精细的多色十字绣几乎可以模拟照片的视觉效果。


十字绣.png

手机显示屏,计算机中像素由于太小了,所以我们看不出它的工作原理,那么下面这个LED显示屏你一定看的懂原理:


LED屏幕.png

这里每个小圆点就是一个[发光二极管],它们的亮与灭,对应了0和1,多个二极管按顺序组合起来,就能模拟显示出文字或是图片的效果了。

单色显示屏的颜色由发光二极管的颜色决定,人们当然不可能满足单色显示,怎样才可以实现一个发光二极管发出各种颜色的光呢?最简单的方式就是把三种颜色的发光二极管做到一起,这三种颜色就是三原色——红色、绿色和蓝色。这三个二极管以不同的亮度发光,就可以组合成多种颜色,比如像这样子:


二极管.png

发光二极管发出光的颜色与材料有关,就好比咱们初中化学学过,铁Fe是明亮的黄色,铜Cu有时候是蓝绿色,溴Br是橙红色等,原理类似。我们把发三种颜色光的材料做到一起,比如上图4条线中三条线对应三种颜色,最后一条线是负极。这样通过颜色组合以及亮度比例,我们就能做到7种颜色了。
目前社会上巨大的广告屏,大部分就是用这个原理做的。

那么,是不是只要发光二极管做的足够小,就可以用于手机或电脑屏幕了呢?答案当然是肯定的。这个技术是近年才出现的,叫OLED(有机LED)不过,因为二极管通电后是主动发光的,材料通电主动发光,意味着材料的损耗与老化,老化的二极管亮度会发生衰减,如果所有的二极管亮度衰减一致倒也还好,但屏幕上的发光二极管因为使用程度不同老化程度肯定不一样,这种不均匀就导致一个硬伤:烧屏,也叫残影,如下图


残影.png

所以虽然OLED主动发光的这个方案可行,但至少目前,在微型显示屏领域,它还不成熟,成本也较高。
我们现在使用的电视,计算机,手机等显示器,还是以液晶显示器LCD(Liquid-Crystal Display)为主。与OLED不同,液晶显示屏本身不发光,而是有一个白色的背光光源。LCD显示屏通过薄膜晶体管控制液晶的偏转角度,进而能控制透过它的背光亮度;透过液晶层的背光再通过彩色滤光片,就变成三种颜色、强弱不同的颜色,进而组合成各种颜色。


原理1.png

每一个液晶显示器都由数百万个这样的三色单元组成,最终成为我们在屏幕上看到的图像。
放大图.png

LCD显示器也有老化的问题,不过它的老化通常是背光光源的老化,是均匀的而不是局部的,因此不会出现OLED显示器的残影问题。一些显示屏用的时间长了颜色不鲜艳、屏幕发黄就是老化的表现。

到这里,我们知道了无论何种类型的显示器,它的每一个像素都是由三种颜色的点组成,这三种颜色分别是红色(Red)、绿色(Green)和蓝色(Blue)。
理论上,这三种颜色的亮度被设置为0-255级,这样一来三种颜色的不同亮度可以有256×256×256种组合,也就是说每一个点可以组合成16777216种颜色,这实际上已经超过了人眼对颜色的分辨力。

不过,与大多数人想象的不一样的是——显示器并不是一次性控制显示面板上所有像素的颜色,而是一次控制“一行”,自上至下地控制显示面板上每一行像素,周而复始。由于刷新的速度很快(一秒钟60次),因此你不会看到屏幕在闪烁,这样做是为了降低硬件设计的复杂度。

如果你用较快的快门速度拍摄老式CRT显示器,你会发现它真的“一行行地”显示图像(液晶显示器不会出现这种情况,但它也是逐行扫描的)

老式显示屏.png

好,讲完了显示屏的成像原理,我们在来详细讲一讲计算机显示图像的过程。也就是存储在计算机中的二进制数据,是怎么转化成图像显示出来的,
此前,就必须讲一讲计算机重要的设备:显卡

二、显卡的简单介绍以及显卡处理过程

显卡(Video Card),也叫显示适配器,是将要显示的图形或文本转换成可以驱动显示器的电信号的硬件,包含以下三个重要组成部分:
(1)GPU(Graphics Processing Unit,图形处理单元,也叫显示芯片)
(2)显存(显示存储器,可理解为内存)
(3)显卡BIOS(Basic Input Output System,基本输入输出系统)

GPU:类似CPU(中央处理单元),显卡也有独立的图形计算单元,用于承担一部分计算任务,不过主要是图形处理上的计算任务。

显存:显卡上的独立存储器,和主板上的内存一样是一种随机存储器(RAM),它用来存储即将要显示的数据。你可以这样理解,程序员负责将要显示的字符或图像数据送入显存,接下来的工作交给GPU和相关的外围电路就可以了。

显卡BIOS:负责存放显示芯片(GPU)与驱动程序之间的控制程序,以及显卡的所有硬件配置信息。比如【字符的显示原理】和【图像的显示原理】:

字符的显示原理
如果我们要在屏幕最左上方显示一个Z:

字符:Z(ASCII码-90)
位置:左上方
则程序输入给显存的第一个字节是90,第二个字节是位置信息,即可。

那么问题来了,送进去的是90,为什么会在屏幕上显示一个Z呢?因为在显卡的BIOS中存储了每一个ASCII字符的图形数据(像素信息),GPU会根据编码取出这个字符像素信息,将其转换成屏幕上显示的电信号:


像素转换表.png

图像的显示原理
与显示字符时直接向显存送字符编码不同,图像的显示要麻烦一点,但本质仍然是向显存送数据。
送的数据是每一个像素的颜色值,例如下面的照片,每一个像素都可以理解成为三种不同颜色的组合,(一个像素内存为3字节,每个字节8位,分别对应R,G,B的亮度值)你只需要将每一个像素的RGB值送入显存,GPU会负责将其转换成电信号并输出给显示器:

图像显示原理.png

参考博文2:一个黑白像素和一个彩色像素分别占几个字节
https://zhidao.baidu.com/question/1115965600101590619.htm

三、图像压缩技术简介

图像压缩技术有很多种不同的算法,这里我只介绍其中比较好理解的两种作为示例:
1.无失真压缩:如行程编码(RLE)(.BMP .TIFF及AVI等格式文件压缩采用此算法)
现实中有许多这样的图像,在一幅图像中具有许多颜色相同的图块。在这些图块中,许多行上都具有相同的颜色,或者在一行上有许多连续的像素都具有相同的颜色值。在这种情况下就不需要存储每一个像素的颜色值,而仅仅存储一个像素的颜色值,以及具有相同颜色的像素数目就可以,或者存储像素的颜色值,以及具有相同颜色值的行数。
这种压缩编码称为行程编码(run length encoding,RLE),具有相同颜色并且是连续的像素数目称为行程长度。
举例

压缩前
000000003333333333
222222222226666666
压缩后
(0,8) (3,10)
(2,11) (6,7)

2.有失真压缩
图像相邻的色块,颜色其实是差不多的,比如(0,200,0)和(0,201,0)
人其实感觉不出来,那么我们就可以把它们统一用(0,200,0)表示,在上面这种RLE算法基础上,又可以进一步压缩

四、小知识:矢量图会取代位图吗?

参考资料:

知乎:既然矢量图放大缩小都不失真,为什么还要使用位图?
https://www.zhihu.com/question/21283005

这个问题我也想了很久,矢量图和位图概念我都清楚,一个是像素,放大会失真,一个是路径描述,放大不失真,但想不明白为何矢量图不能代替位图。直到看到该篇中的回答解释,才豁然开朗。
王新驰一句话概括:
矢量图是由点线面构成的,它不是相机拍出来的,而是人为软件绘制出来的。
所以矢量图是【画】,而位图是【像】。如果制作一幅细节还原到逐个像素水准的矢量图,那么它不是已经变成了位图(用阵列模拟位图画),就是有着惊人数量的矢量元素和恐怖的文件体积(用线面色勾画);

以下取自知乎一个叫冬月的人的解释:
...
这个问题太有趣了,我也想过很久。我觉得“图像”本身就是人类承载视觉信息的一种文明产物,如果我们非要追求一种真正能说成完美的图像形式,那么我们最后会发现,还是要去长城亲眼看一看才行,而不是呆在家里上网看图,或者干脆在自家后院建一个长城。“图像”作为非物质、信息的形式,它必须利于传播,容易编辑,而效果只要能够满足人们的需要就够了。位图和矢量图的区别下面做个例子,如果用信息形式记录下来,它们是这样的:位图:在位图中,理论上图像必须由像素点阵组成,图像任何一个角落都是平等的,都忠实记录着信息,哪怕写个“无”字,都要一板一眼写好,哪怕这些信息组合在一起仍然是毫无意义的成片单个颜色。比如“一无无无无二无无无三无无四无,另起一行,无无无……”等到看的时候,只需要展开这段记录,把它展开在平面就行了。下面这张图片是字符画,但已经可以大致反映出“位图”这种图像形式的基本特征:


位图1.png

我们平时看到的位图,原理上基本就是这种构造。聪明的人们很快发现,位图里一些单色区域真的可以省略处理。是的,从人类会画画开始,就知道用单色墨水一下子泼出一片黑、一片白之类,而不是一笔一划地傻乎乎涂大片相同颜色,所以无论是电子设备的照片文件,还是印刷,也都可以借助这个办法省很多功夫。于是,人们专门创造出一些省略规则来搞定位图中那些毫无意义信息,就可以把“无无无无无无无无无无”写成“十个无”。到这里,人们打开了一闪新的大门:“位图文件压缩。”然而人们还不满足,比如一个空位可以从无到一,一直包含到十六万,那么平时大家也分辨不太出十万八千和十万八千零二十的区别,那我们干脆把容许偏差提升一点吧!反正也不容易看出来!这就是“有损压缩”,有损压缩情况下,只允许丢失信息和精确度的。可是追求完美的人们想既让文件细节不丢失,又想让文件体积变小,于是又想出个办法。如果把“无无无无无无无无无无”记成“十个无”是通过“找规律”来“无损记录信息”,那么找到更多规律的话,就可以节省更多空间,还不会丢失信息啦!人们结合了古今智慧,各种数学算法,找到了多不胜数的规律,大规律套着小规律,小规律套着老规律,最后把位图里认为适合用规律记录的部分,来用规律记录,剩下难以用规律记录的部分就少了,然后,把它们编写形成一个文件,让图像文件变得更小,这就是“无损压缩”。但是,人们在“压缩”这条路的最开始,只要记住“十个无”、“一百个无”在展开图像时候是什么意思,就能完成展开,但随着压缩算法越来越复杂,需要记住的也就越来越多,于是人类必须准备一本“密码对照本”;效果越好的无损压缩,需要用到的“规律”——“压缩算法”就越复杂,“密码对照本”就越厚。最后,人们发现,信息传播大体规律就是这样,一个眼神能传情,就需要两个人都有一套细致的感情密码本。而且人们给位图定制了很多本密码本,就是我们常见的各种“(位图)图片文件格式”,比如jpg。位图的“图生”也就基本这样了。这时候,矢量图要出场了!什么位图?什么乱七八糟的无无无?我们传播和记录那些无意义的东西干嘛?我们要传播的是信息!是画面!画面不就是点、线、面、位置吗?那我直接记录这些信息不就得了吗?你要直线,我就给你根直的,你要曲线,我就给你弯的,你要什么颜色,我就给你什么颜色,不就得了吗?隔壁位图抱着厚厚的密码本,也只不过是用来记录代码规律来压缩文件,那我干嘛记录代码规律?我直接记录图形规律多省事?就这样,矢量图被创造出来了。任何线条、颜色都有规律,是圆是方,是红是白,怎么放置,记一下,完事。矢量图:“用黑色,画个圆,圆上方画个波浪线,一个浪比一个浪大那么一丢丢,好嘞。”


矢量图.png

这就是矢量图的文件形式。可以想象,矢量图需要记录的东西,往往比位图少很多,所以,矢量图文件通常也很小。

矢量图:“位图先生,你在一亿像素屏幕或者打印机上无损还原一千条曲率不同颜色不同的线需要几行代码呀?”
位图:“9102年了,我已经发展很久,不比你大多少……,无损这件事嘛,emmmm我们现在升级到视网膜分辨率了……”
矢量图:“敢把无损压缩算法的密码本掏出来看看多厚吗?”
位图:“……”
矢量图:“放大一百倍之后,矢量图先生会不会满眼像素点啊?精确度能分毫不差嘛?”
位图:“你走!别跟我说话!”

位图如果要记录一个圆,要用像素码成个圆,而矢量图记录同样的圆,只需要写一个“圆”字。由于矢量图只记录“点、线、面、位置等等”这些人类认知种存在的抽象信息,所以有着完美的精确度和还原度,但这不意味着矢量图是完美的。矢量图的最根本缺点是,它所采用的构成元素(点线面),往往是自然界并不存在的东西,是抽象概念,所以也难以在自然界中直接采集,而是必须经过人工或计算机测量、思考运算来转换生成。所以我们常见的矢量图,往往都是出自人手,而不是采集自镜头。一旦需要完整记录复杂的图像信息,那么矢量图就需要去“有意识”地特意绘制那些细节才行,图像需要记录的细节越复杂,矢量图要记录的信息也就越复杂。同样情况下位图只牺牲一点压缩效率,甚至可以不压缩。这时候位图虽然没法绝对精准,但至少能够记录细节,而且像素越高,镜头越先进,成片就越接近完美,技术上还是瞬间就能捕捉完成的。所以,最后矢量图羞涩地躲到绘画软件里,陪着设计师们搞创作,一副乖巧的样子。简言之,位图是记录一定精度的“像”的图像形式,而“矢量图”是记录想象中、意识中的“画”的图像形式。如果制作一幅细节还原到位图逐个像素水准的矢量图,那么它不是已经变成了位图(用阵列模拟位图画),就是有着惊人数量的矢量元素和恐怖的文件体积(用线面色勾画);同样,如果制作一幅图形精准度能达到矢量图水平的位图,那么它需要的像素必须是无限大(比如画一个无论放大多少倍都没有像素锯齿的圆,就需要无限像素)。“惊人、恐怖”没有“无限”多,所以理论上矢量图赢了,矢量图理论上可以取代位图,位图无法取代矢量图,但这个说法的前提是,人类必须时时看到达到数学级别精准的图形图像,并且接受矢量图在这种情况下丧失优势,膨胀起来的体积。很显然,这没必要。所以我们要讲究够用就好,因为“图是给人看的”这个基于信息传播角度的大前提,让位图“负责现实”,矢量图“负责想象”,两者各司其职吧。

五、主流图片文件的区别与发展

所有的图片文件,其本质无非是编码解码方式不同,不论是始祖BMP还是后来的有损压缩JPG,还是再后来的无损压缩PNG,它们只是压缩编码方式和解码方式不同,本质上还是二进制文件,存储的仍然是01010101这种数据。下面介绍几种常用的图片格式。

1.BMP(Bitmap,Window标准位图)

特点:无损,文件大
最普遍的点阵图格式之一,也是Window系统下的标准格式,是将Window下显示的点阵图以无损形式保存的文件,其优点是不会降低图片的质量,但文件大小比较大。

2.JPG/JPEG(Joint Photographic Experts Group,联合图形专家组图片)

特点:有损,文件小,兼容性强
最适合于使用真彩色或平滑过渡式的照片和图片。该格式使用有损压缩来减少图片的大小,因此用户将看到随着文件的减小,图片的质量也降低了,当图片转换成.jpg文件时,图片中的透明区域将转化为纯色。

3.PNG(Portable Network Graphics,便携式网络图像格式)

特点:无损,文件小,兼容性比JPG稍弱
适合于任何类型,任何颜色深度的图片。也可以用PNG来保存带调色板的图片。该格式使用无损压缩来减少图片的大小,同时保留图片中的透明区域,所以文件也略大。尽管该格式适用于所有的图片,但有的Web浏览器并不支持它。

4.GIF(Graphics Interchange Format,图形交换格式)

特点:无损压缩,文件小,解码速度快
它有两个版本发展过程
1987年推出的GIF87a版本,一个文件存储一个图像,不支持动图
1989年推出的GIF89a版本,允许一个文件存储多个图像,可实现动画功能,允许某些像素透明。

结尾小结

计算机存储本质是什么?
计算机所有的文件均为二进制文件,包括文本文件(它是特殊的二进制文件,为什么特殊?因为它里面全部可直接翻译为字符),这些二进制文件就是一群0101集合(特定软件能打开就能看到),他们的读取与写入,过程完全相同:
读入内存:文件-->二进制流-->-->按格式解码-->应用程序内存数据
写出文件:应用程序内存数据-->按格式编码-->二进制流-->文件

需要认识掌握的几种常见图片格式
.bmp:Windows标准位图格式,不压缩,体积大,
.png:便携式网络图形格式,无损压缩,小巧,最优秀
.gif:图形交换格式,无损压缩,一个文件可保存多个图片,可做动画
.jpg:jpeg格式,有损高压缩,小巧,最广泛应用(视频用的就是这个)

你可能感兴趣的:(《图片文件前世今生和衍生技术原理》)