89. 钻钻牛角尖:像素是如何绘制到屏幕上的?

这次的音频又超时了,超过30分钟不让传,打赏后请移步网易云音乐或者喜马拉雅App收听,哈哈。

我的个人微信号是: liuyandong00


  • 1. 造一根铅笔复杂么?
  • 2. 像素和屏幕的关系
  • 3. 硬件和软件协作
    • 3.1. 硬件部分主要是显卡和CPU
    • 3.2. 软件部分主要是OpenGL/DirectX/Metal
  • 4. 栅格化和合成
  • 5. 透明度
  • 6. 像素
  • 7. 图像格式
    • 7.1. JEPG
    • 7.2. PNG
    • 7.3. 该采用哪个呢?
    • 7.4. 最后

不知道大家有没有这个疑问,就是电脑上或者手机上的东西,如何显示在屏幕上。在显示的过程中,到底发生了什么事情?反正我一直有这个疑问,在初中时候就有了,现在都已经30多岁了,还是有这个疑问,我大学时候就试图搞清楚这个问题,做了很多事情,试图研究明白。现在我也只能说个大概的情况,因为现在技术太先进了,从以前的阴极射线管,到液晶,到后来的LED背光,再到现在的OLED技术,连背光都不使用了。

其实OLED技术只能通过东芝和三星的宣传,知道一些皮毛,实际到底是怎么工作的,我觉得除了这两个厂商以外,没人知道精确的工艺流程。就像我们的教科书里,初中就学了发动机的原理,但是实际上能制造靠谱发动机的公司没几家。甚至就是人家把设计图,生产流程以及标准都告诉你了,还是造不出来,因为这还牵扯一个供应链的问题,最后很可能是钢材不行,刚才不行是因为炼钢工艺不行,炼钢工艺不行又会牵扯到更多问题,最终导致的结果就是,好像很简单,就是造不出来。

1 造一根铅笔复杂么?

可能有些人觉得我说的太扯淡了,怎么会牵扯到那么多工艺,不就是一个显示器或者一个发动机么,给个图纸,立马给你造出来。我举一个更简单的例子吧,来说一下供应链的复杂程度。我就拿铅笔来举例吧,就是我们小学时候用的铅笔,看看会牵扯到多少工艺以及产业链。我们买一根铅笔,首先,木头是哪里来的,我们可以想一下,大概就是老天爷种了一片森林,然后被我们砍了,伐木工人可能会使用各种工具,这个我们不去仔细深究了,否则根本没法深究下去。伐木工人在砍树的时候,100%不知道这棵树会被制造成铅笔。

我简化一下,有一棵树被砍了,送到一个工厂,大树被加工成了木条,然后,这些木条又被另一家公司买去,这个公司可能是铅笔厂。我们写字用的铅笔,里面那根铅,其实不是金属铅,而是石墨,石墨是一种矿物,我们山东省是产石墨的重要产地,非常复杂,不是我们认为的挖出来就可以用,而是要各种提炼,最后才是石墨的成品,污染非常严重的一个行业。石墨厂制造的石墨也不是只用来做铅笔,但是石墨厂不管这些,因为石墨也是用来做塑料的重要原料之一,这里我们还是不去深究,深究下来,根本没法弄,我当年年轻时候总是想打破沙锅问到底,实际上这不可能的,我们再假设,石墨已经搞来了。

铅笔芯也不是全都是石墨,而是石墨混合粘土,粘土这个东西吧,也不是我们开个挖掘机挖两下,这种叫土,粘土是土的子集,粘土也是一种重要的资源,这里还是不能深究。我们再假设石墨和粘土混合以后,铅笔芯已经造出来了。铅笔上还有个橡皮,橡皮这个东西并不只是橡胶,里面有另外一种东西,叫硫化油膏。不信大家可以拿一块橡胶去擦铅笔字,根本擦不了去,越擦越脏,黑乎乎的一片。因为橡胶里没有硫化油膏。这个硫化油膏怎么造出来的?我不知道,我也没查到,我估计铅笔厂的员工也不见得知道硫化油膏的生产流程。

还有铅笔上固定橡皮的那块金属,还有铅笔上的涂料,这个我就不说了,因为我根本不知道怎么弄出来的。就是有维基百科,大英百科全书,也够呛能搞的清清楚楚。

我为什么要说铅笔呢,因为这个东西最常见,如果往深了研究,也是一头雾水,根本搞不懂。更何况我是试图说一个不常见的东西,如何把像素绘制到屏幕上,这里面牵扯到CPU,显卡,以及OpenGL,DirectX,还有苹果手机上的OpenGL ES,然后才是屏幕,因为屏幕也已经很多种了,LCD,OLED,苹果的视网膜屏幕等等,用的技术肯定不同,我没法深入聊下去,所以,也只能点到为止。希望大家理解,往深了研究,每一个细小的领域,都能耗费一个人的一生。

既然是瞎扯,我还是说说我的看法,如果有人听我的音频,不要太相信我说的事情,首先要怀疑我是在瞎扯。比如等一会儿我在计算像素的时候,不同的屏幕计算像素是不同的,因为屏幕不一样,所采用的技术不一样,像素点肯定有差异,而且差异会很大。但是,具体细节我根本不懂,我曾经和一个三星的朋友聊过,他们的屏幕为了讨好人类的眼睛,再加上有些技术不成熟,采用的技术好像是两个绿色像素对应一个蓝色和一个红色像素,所以,三星的有些屏幕颜色是偏绿的,但是我在接下来的扯蛋中,就假设RGB,一个红色,一个绿色,一个蓝色,教科书里的三原色。可能和现实中的显示器有很大的出入。大家还是要怀疑我说的话。包括网上很多节目,或者很多文章,也建议大家多长个心眼,谨慎的相信。并不是人家有意误导你,更大的一个可能是,那个写文章或者做节目的人,他自己也有盲区,他也搞不明白,但是他自以为自己懂了,然后很自信的在那里胡诌,也是非常可能的。比如我自己也对物理非常感兴趣,我本身是数学系的,经常去物理系听课,当年觉得自己可能当个物理学家啥的,我年轻时候很天真,学了非常多量子物理。现在我也经常看看量子物理的节目,然后我发现,很多敢写文章或者敢做视频音频的人,只是大胆而已,就和我敢做软件那些事儿一样,并不比别人懂得多,就是大胆,敢胡扯。比如他们讲的时候,偏八卦,说实在的,我不认为普通人,尤其是数学能力不够的人,能真正的弄懂量子物理,即使觉得自己懂了,其实也都是一些创造性的误解。如果连一维,二维薛定谔方程,定态薛定谔方程都看不懂,还有希尔伯特空间,角动量耦合等等这些一看就晕菜的名词,这些搞不懂,还不如了解一些物理学家的八卦呢。我在这里既然讲到薛定谔了,其实薛定谔是物理学家中泡妞水平最高的人,只限于物理学家,要是跨界到了哲学家领域,他连个菜鸟也不算,比如和罗素这些大哲学家比泡妞,薛定谔得去死。薛定谔是一辈子泡妞,生命不息,泡妞不止,反正在物理学家中,他应该是毫无争议的老大。所谓不是一家人,不进一家门,薛定谔的老婆也是高手,老公在外面泡,女人能顶半边天,你泡我也泡,薛定谔泡妞追求的是数量,他老婆追求的是数量加质量,两手抓,两手都很硬。他老婆在物理学届泡的是薛定谔,然后跨界泡了一个数学界的扛把子,在数学界的地位不亚于物理学界的薛定谔,他的名字叫赫尔曼•克劳斯•胡戈•外尔,简称外尔,学数学的应该知道他,20世纪最有影响力的数学家之一。而且,外尔也有老婆,外尔的同事更出名一些,叫爱因斯坦,他俩都在普林斯顿工作。薛定谔老师和外尔老师是一生的朋友。他俩都受聘于苏黎世大学,然后,反正关系有点混乱…那你说外尔老师的老婆不生气么?你还别说,人家就是不生气,外尔老师的老婆是犹太人,按理说应该有点三从四德吧,结果,她也不,既然老公和薛定谔的老婆很忙,她也不好意思和老公吵架,万一影响了感情多不好,外尔的老婆还是为数学界扳回了一分,他作为数学界的代表,又撬了一个物理届的大牛,瑞士物理学家保罗谢尔,可能大家不太知道保罗谢尔,现在瑞士有个研究所叫保罗谢尔研究所,在物理界还是比较出名的。那保罗谢尔也是有老婆的,那他老婆怎么办呢?要形成一个闭环吧?算了,不讲这些事情了,大家还是好好学习,多听听别人讲量子物理,我在这里讲这些八卦,有损我这个节目的严肃性,不过,希望大家知道,人家科学家的度量和眼界,不是我们这些平凡人所能理解的。好了,讲正题。

2 像素和屏幕的关系

我先来说一下屏幕,主要说苹果的屏幕,因为苹果设备型号少,像三星,前面我说了,可能有些不太一样。每个像素,是有三个颜色组成的,就是RGB,分别是红色,绿色和蓝色,这三个颜色是独立的,然后这三个颜色会合成在一个像素上。比如说,现在的苹果7plus,分辨率是1920×1080,因此颜色单元就是1920x1080x3=6,220,800(六百二十二万零八百)个颜色单元。如果是苹果最新款的imac 5k屏幕,分辨率是5120×2880,因此颜色单元应该是5120x2880x3=44,236,800(四千四百二十三万六千八百)个颜色单元。为了能保持流畅的视觉效果,还要保证滚动的时候,每秒60帧的刷新,这是一个非常大的运算量,因此,一般的显卡扛不住。

3 硬件和软件协作

电脑么,都是软件和硬件协同工作,只堆硬件如果不优化的话,效果并不大,类似于在高速公路上骑自行车,速度并不会有质变。

3.1 硬件部分主要是显卡和CPU

每一台电脑和手机上都有CPU和GPU,CPU就是中央处理器,GPU是显卡。这两个分工不同,CPU是一个通用的大脑,显卡处理的,实际上CPU都可以处理,只是处理的不够快。显卡主要是为了图形高并发计算量身定做的处理单元,功能比较单一,就是同时更新上面我提到的那么多像素,并且让它显示在显示器上。GPU做这些工作非常高效,相比CPU来说,完成图像合成这个工作,用的电也更少。(正是因为GPU计算能力突出,所以也被广泛的用来挖比特币)。

GPU是一个计算能力非常强大的硬件,他连接到CPU。从硬件上讲,CPU和GPU之间存在某种类型的总线,并且在软件和硬件的协同下,来传输数据。接下来讲软件部分。

3.2 软件部分主要是OpenGL/DirectX/Metal

显卡是硬件,只用硬件是不行的,显卡得有相应的驱动程序,也就是软件,在苹果手机和电脑上,以前的时候用的是OpenGL,现在已经不用了,现在苹果自己家搞了一个Metal的东西,现在这个只支持最新的几款手机,好像是iPhone 5s以后的机型。微软家也有一个叫DirectX的东西,玩游戏的都知道这玩意。

大概的原理是这样,CPU发指令告诉GPU,然后让GPU渲染一个东西,比如渲染一个炮弹爆炸的效果出来,然后显卡得到指令以后,就开始干活。总体来说,CPU还是掌控全局,GPU只负责显示的部分。但是最近几年,显卡领域的性能突飞猛进,远远超过CPU领域。大家也都知道,在CPU领域实际上最近几年没有太大的发展,像Intel,一款CPU卖3-5年,挤牙膏一样。但是在显卡领域,尤其是手机显卡领域,PPT大户苹果公司,经常宣称这一代显卡比上一代显卡又增加了几倍几十倍,好像是现在的iPad比第一代iPad的显卡性能增加了180倍,当然了,我个人认为这个数据有可能有水分,但是,水分肯定比乐视公司的PPT要小一些。大家随便听听就好,发布会上说的话,也不能去打官司。

OpenGL实际上已经江河日下,已经难以达到当年的辉煌了。在遥远的1992年,大部分听众都没有出生的年代,OpenGL首次发布。在OpenGL之前,每一款显卡都有自己的一套标准,开发的软件每次都要根据不同的硬件,分别移植一下。这应该是相当的痛苦!然后,OpenGL,他的全称叫Open Graphics Library,出来拯救程序员了,OpenGL提供了一个图形渲染的API,这样的话,只要调用相同的API,程序员就不用为每一款GPU重写一份软件了。简直就是解放前和解放后的巨大差别。

4 栅格化和合成

讲一下大概的一个工作流程。比如说,我们在电脑上魔兽世界这个游戏,这是我最喜欢玩的游戏,现在已经不流行了,我年轻时候特别特别喜欢玩,每天大概4-5个小时贡献给了部落,为了部落。既然说到了我最喜欢的游戏,我来说一下我对魔兽世界的看法,魔兽世界毁誉参半吧,比如很多人看到自己的孩子沉迷于游戏,就把自己的孩子送到杨教授那里电击。游戏到底玩的是什么呢?我打了四五年魔兽世界,现在我已经不打了,最近几年我都不再登陆我的账号了。我认为魔兽世界玩的是友情。在艾泽拉斯,我从来不后悔我投入的那几年时间,每天四个小时左右。如果时光倒流,让我再做出选择,我还是会做出同样的选择,玩魔兽世界。

我在现实中不是一个朋友遍天下的人,我见到陌生人也不爱打交道,虽说我几乎不和别人发生冲突,但是总感觉谈不是朋友,也谈不上敌人,现在毕业多年,那些同学也渐渐的疏远了,同学聚会的时候,话题也不多,只剩下一些回忆。有时候,我觉得上学时候留下的回忆,还不如我玩游戏时候留下的回忆美好。在魔兽世界中,我不觉得我是在逃避现实,可能有人觉得是这样。在魔兽世纪游走的那四年,我看过恶心的事情,比如骗别人的钱财,比如坑别人的金锭。但是,也见过很多美好的事情。比如和工会的朋友一起打架,和好基友一起去北极钓海龟,去达拉然日暮喷泉去捞金币,好多好多的事情,一幕一幕的在脑海里浮现。

我在公会里算是打的比较好的人吧,后来我又练了两个小号,因为四年对一个人来说,是很长的事情,对恋爱高手来说,四年可以换20个女朋友了,我就把两个小号又练起来了,在期间,总是会碰到值得珍惜的战友,一起去打很强大的敌人。然后,在游戏中认识的人,一个一个的离开了游戏,有些是因为家庭,有些是因为工作,有些是因为毕业了,肩上的重担开始让你不得不离开游戏。工会里慢慢的不认识的人越来越多,然后,在某一天,我也留言告诉大家,我也要离开了。在离开的一两年里,我就用小号去登陆一下,去看看艾泽拉斯的风景,也很希望能遇到自己认识的战友,聊几句,或者只是去看看草原上跑来跑去的动物。

有时候,非常的想念工会里的战友,虽然,我们只是在游戏里相遇,也不知道他们现在在那里,有时候,我就会想,他们会不会想起我?其实,他们忘了我也没什么关系,反正我记得他们,他们陪我度过了很快乐的四年,我祝福他们,一生都有好运吧。

好了,再讲一下大概的工作流程。比如打开游戏的时候,会有魔兽世界的图片加载到内存里。这里的内存是主机的内存,比如是一张PNG图片吧,这时候CPU要解压这张图片,然后通过某种方式,将这个图片从主机内存里,加载到GPU的内存里,也就是我们常说的显存里。显卡需要将一个frame的纹理合成出来,而且一秒钟要合成60次,每一个纹理都要占用一些显存,也就是说在16.7毫秒的时间里,显卡要不停的在干相同的事情。CPU告诉显卡,某个位置要显示什么东西,然后显卡就去显示。因为有些纹理是不变的,所以,显卡会重复使用已经存在的纹理,并不是每次都重新计算。

每一个纹理实际上是一个长方形,我们的电脑还是手机,都是一长方形来布局的,在苹果电脑或者苹果手机中,可以等价于是一个CALayer对象,CA代表Core Animation,如果给苹果开发过软件的同学应该知道Core Animation。这样的话,每一个layer就是一个纹理,所有的纹理又有可能互相的层叠。如果大家用过Photoshop的话,应该知道,这个类似于一个层一个层的,每一层都会影响到下面的层。因此,如果桌面上的窗口很多,这种互相影响就会变得非常复杂。计算这些层之间互相影响的过程,叫合成。

合成是有一个公式的,这个公式是 R = S + D * (1 – Sa),意思是,合成的结果 = 源色彩(顶端纹理) + 目标颜色(被顶端盖住的纹理) * (1 – 源色彩的透明度)。我们可以假设一下,如果最上面的这一层是透明的,那么结果就是最顶端啥也看不见,直接显示第二层的颜色。如果最顶端是不透明的,那么第二层啥也看不见。根据这个公式,如果透明度不是0或者1,而是介于0和1之间的一个值,那么最后得到的颜色就是半透明的。

5 透明度

透明度是个值得说一说的事情。我们在用windows的时候,控制面板里有个选项是可以调整最佳外观和最佳性能的。当调整为最佳性能的时候,一些半透明的效果就没了,比如没法显示半透明的选择长方形。因为,如果使用半透明的效果,就会非常耗费资源。根据上面我讲的那个公式,如果最上面的一层是完全不透明的,那就省事儿,直接不用计算,因为后面的都挡住了。如果最上面的一层是完全透明的,那么也很省事儿,直接计算第二层和后面的几层。因此,我每次用电脑的时候,为了能减轻显卡的工作量,一般是从来不使用半透明状态。我这样也算是有爱心的表现吧,感觉比国内不少爱狗人士的爱心要好很多,我起码不会去公路上拦车,去砸店。自己爱狗是好事儿,你不能去把人家赖以为生的店给砸了,然后还理直气壮。

6 像素

前面讲过,像素由RGB组成,代表三种颜色,红绿蓝,就是我们常说的RGB数据。那么这些数据该如何存储在内存里呢?正确的答案是,每家公司根据每款产品的不同,存储的方式也不相同。感觉这是一句废话,但是现实就是这样,毕竟是编程,每种方法都有自己独特的优点和缺点,不同方法之间各有优劣,很难说一种方法能彻底碾压另外一种方法。这一点和社会主义和资本主义不相同,因为这两种主义中的一种可以毫无疑问的碾压另外一种。

在实际的计算机中,除了RGB,还有一个透明度,所以,每个像素中实际上可以得到四个数值。就是ARGB,每个像素占用四个字节,每个像素有一个alpha值。最终,RGB的值需要乘以alpha的值,这样得到一个最终的值。这是其中的一种表示方式,这种方式就叫ARGB。

还有一种存储方式叫xRGB,这里没有alpha值,所有的像素都被假设是完全不透明的。这种方式也非常的流行,因为这样会节省25%的存储空间,而且这种格式对CPU和GPU来说也很友好。不透明是个好事儿,在合成的时候,计算量也会小很多。

7 图像格式

我们最常见的两种图片格式是JPEG和PNG,如果用的是普通手机的话,这两种格式最常见。当然我见过有些摄影器材爱好者,拍照片用RAW格式,数码底片,这个不在我的讨论之列。在这里只讨论JPEG和PNG。

7.1 JEPG

很多手机和个人小数码相机默认的图片格式就是JPEG格式。JPEG是一种压缩图片,比如一个未经压缩的照片可能是30M,使用压缩以后就是2-3M左右。尺寸就是原来的1/10。之所以压缩效果这么好,是因为这种压缩格式是有损压缩,JPEG上的很多人类不易察觉的信息,就被丢掉了,实际上这个图片和原来的图片相比,是失真的,只是绝大部分人看不出来而已。

还有,JPEG和上面所讲的RGB像素布局之间的区别是雷锋和蜜蜂的区别,这个JPEG和RGB完全没关系,如果不是完全没关系,也是99%没关系,JPEG不是一种像素数据格式,而是一种压缩格式。JPEG将原始数据换成了像素数据的过程一点都不简单,如果正常人的话,从零写一个能读取JPEG的程序,不使用任何现成的库函数,至少1-2周起步,知乎上的天才一小时起步。我当年借鉴了各种源代码,自己憋了半学期才勉强搞定,这个算法非常复杂。JEPG使用的是一种余弦变换的算法,叫DCT变换,然后将空间信息转换到频域,然后再量子化,再排序,最后再使用哈夫曼编码来压缩。如果读图片的话,就是一个可逆的过程,所以我个人觉得,一点都不简单,虽然现在我们使用的工具,双击就可以打开一个JPEG图片。

7.2 PNG

还有另外一种非常常见的图片格式叫PNG,这个和JPEG格式截然相反,这个格式是无损的,如果一个图片被保存成PNG格式,所有的数据和最初的数据是一样的,没有任何损失。而且PNG格式的解压会更简单。那是不是说PNG格式会比JPEG格式更好呢?

当然不是了。PNG格式有大量的变种,和X战警上的变种人一样,有很多优化了的PNG格式,比如使用苹果手机的软件,如果有人有兴趣反编译一个苹果软件,会发现里面有很多PNG后缀的文件,但是,拷贝到电脑上,就是打不开。为什么呢?因为这就是XCode对PNG格式的一种优化。优化以后的PNG文件,已经不是电脑上可以打开的PNG文件了,如果你想打开,还得需要使用一种软件,网上有好几个python脚本,开源的,可以把这个优化以后的PNG文件还原成电脑上可以打开的PNG文件。

怎么优化的呢?其实我也不知道怎么优化的。最终的结果我倒是知道,就是改变了像素的布局,前面我不是提到过么,不同公司的不同软件会采用很多种方法来存储RGB数据,苹果手机上的数据肯定对苹果手机的软硬件做了相应的优化。

7.3 该采用哪个呢?

我个人觉得随意,尽量用这两种图片格式,PNG和JPEG都行。如果没有特别的把握,不要贸然自己给自己挖坑,写了自己一种特殊的图片格式,大家有兴趣的话可以搜索一下图片漏洞,看看有多少致命的bug都是图片解压缩算法引起的。万一我们自己山寨的图片格式在解压缩的时候,被人给了一个经过处理的格式,里面隐含了一条命令,把服务器给删除了,这个也有先例,传一张图片,就拿下一个网站的root权限。我个人感觉,JPEG和PNG这两种被广泛应用的图片,大概,也许,可能已经杜绝了一些特别致命的隐患。要是自己山寨,玩玩可以,用到了生产环境,可能会得不偿失。

7.4 最后

好几个人问我什么时候更新编程的视频,我不打算更新了,因为那些视频给我带来的困扰非常多,总是有人来让我调试,而且总是催来催去的,我觉得,大家不能对免费的东西有售后服务的想法,我不可能帮助调试软件的,以后我不会再录编程视频了,我也不解答任何有关编程的问题,发那么多截图来,实际上我连看都不看,首先看不清,其次,我也不想回答类似于我不想用xcode,能用windows给苹果编程么这种无聊的问题,我就帮你百度一下,把链接发给你。欢迎关注我的公众号,软件那些事儿。当然,更欢迎你打赏我。

0 0 投票数
文章评分
订阅评论
提醒

0 评论
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论x
滚动至顶部