simpread 屏幕适配原理解析
本文由 简悦 SimpRead 转码, 原文地址 www.jianshu.com
想写这篇文章很久了,一直手懒,不爱整理,毕竟这块内容非常枯燥,其实核心原理是比较简单的,单是因为涉及的常用尺寸比较多,所以还是有必要死记的(总不能每次都从头计算一遍吧!)。
刚开始学习 UI 得时候不熟悉安卓和 iOS 屏幕适配,曾经在网上做了大量的资料搜集,但是没有一篇可以讲通彻的,于是自己从屏幕工作原理开始研究起,整理网上查到的资料,最终掌握安卓和 iOS 的适配,同时还了解到 PC 和 MAC 屏幕的区别(原理相通)。
温馨提示!本文相当枯燥晦涩,不具有权威专业性,只是个人理解。只讲适配原理,不讲设计规范!
下面这句话已经翻烂了:由于安卓系统的开源特性,导致各大手机厂商推出了由自己设定的尺寸的屏幕,这就是屏幕的碎片化;同样 iOS 也在其不断更新迭代中,不断产生新的尺寸的屏幕出来。如下图:
数据来自友盟,图中每一个方块都代表一块不同比例的屏幕
数据来自友盟,每一个方框代表一块统一倍率下不同分辨率的屏幕
这种现象增加了用户选择多样性,促进了消费,但是对 APP 的设计开发人员造成了不小的麻烦,要知道手机只是承载获取信息的工具,内容才是主导消费的中坚力量。如果没有一个合适的解决办法,app 设计师和工程师就需要对每一种屏幕都进行适配,这是相当消耗人力物力的。好在,人类是伟大的。
一、名词解释
先来熟悉一下我们会用到的单位和名词:
像素
像素是图像元素的简称,英文 Pixel 来自 picture+Element 的组合(另外一种说法是 picture cell),像素没有单位,或者说像素的单位是 “个”,也可以说像素本身就是一个单位,下面会讲。
一、物理意义:
屏幕中显示图像的最小发光单位,(oled 屏幕)一个像素体由三个发光二极管构成,分别发出红光、绿光、蓝光,具有物理体积。
像素体的大小不直接用体积或所占面积来表示,而是用比较宏观的单位 “分辨率,即:单位物理尺寸内所含的像素数量” 来描述相对大小。
像素点不一定是正方形的,这跟不同的屏幕技术、色域等有关。如下图:
LCD 屏微观照 https://www.bilibili.com/video/av18010287/
AMOLED 屏幕像素微观 https://www.bilibili.com/video/av17119321/
_插一段:_随着技术的不断进步,像素点是可以继续缩小的,就是说屏幕的精度也将继续提高,LCD 屏幕采用背发光,需要白色发光板来照亮带三种颜色的微小晶体,通过液晶层调节通光阀门,控制白光在单个晶体的通光亮,从而控制三种颜色色晶体的亮度,最终混合成我们所需要的图像颜色,这种屏幕的黑色是要耗电的深灰色,而不是纯黑;相比之下 AMOLED 屏幕就牛逼了,每个子像素都可以自己发光,自己关闭,因此它的黑就是真正的不通电,这就是 AMOLED 比 LCD 屏鲜亮轻薄省点的原因,不仅如此 AMOLED 的屏幕因为没有背光板和液晶层所以可以更薄,可以弯曲折叠,而不影响最终成像,这就是目前的曲面屏。
这根我们要讲的屏幕适配没有直接关系,只是你需要明确了解像素这个物理实体。
二、虚拟意义:
1. 屏幕中一张图片的像素大小是 100x100px,说的是屏幕里这幅位图是由 10000 个色点 空间混合而成的,注意:这里的另一层含义是图片的像素大小是 _虚拟量_,是供计算机识别的单位。图片像素大小是描述图像尺寸的唯一因素,没有任何场景的情况下说一幅图片分辨率是 72ppi 或者 300ppi 都是完全错误的,分辨率将在下面讲到。参考 https://www.jianshu.com/p/e7a53ac55454
远看
近看
_稍微提一下,可能不完全正确_:为什么说像素是描述图像尺寸的唯一因素,这要说到图片的来源 – 数码相机
数码相机通过感光元件 CCD 电荷耦合器件来接受镜头折射来的光线,我们常说 2000 万像素后置柔光双摄照亮你的美,就是说这台手机的 CCD 上有两千万个感光元件颗粒(也叫做像素),这个东西比屏幕上的像素更牛逼更细小,这就说的是摄像头的解析度,而不是分辨率(错误说法),因为每个颗粒只能记录一种颜色,所以通过这个元件生成的图像就有两千万个像素点生成,这种图像也叫做位图,每个元件摄取的颜色方块是可以无限放大的,所以位图可以无限放大缩小,没有固定的物理尺寸,但是放大后看到的是密密麻麻的小方格,离远了看就成了一幅图像,这涉及到眼睛的成像原理,艺术中也叫空间混合,有兴趣可以继续深究(我是懂了,不解释)。位图可以被细化像素数,也就是改变图像像素大小(ps 就可以做)但是不会提高清晰度,因为相机已经决定了他的清晰度(包括通光亮、色值、像素数),现在谷歌 AI 算法可以通过卷积神经网络深度学习技术 balabala 来重新成像,极高的提高清晰度,不解释(我是懂了)。
2. 像素作为屏幕解析度的单位来使用,例如:
iPhone8 的解析度为:750x1334px,意思就是 iPhone8 的屏幕上有 750x1334=1000500 个发光二极管(解析度下面讲)。
三、与其他基础单位的区别(px、pt、dp、sp)
pt 与 px
a. Point 磅、点,缩写 pt:描述字体大小的物理单位,用于印刷行业,1pt=1/72in。
_插一段:_Apple 公司最初的 Mac 屏幕分辨率只有 72ppi,所以 Mac 上显示的 72px 的图像就是 1inch 那么长,只不过苹果把 px 改成了 pt(所以这里的 pt 是虚拟单位),与印刷行业保持一致(与当时市场环境有关);微软是个人电脑的先驱,最初将屏幕做成 96ppi,就是说 96px 大小的图片显示出来就是 1inch 那么长,但是微软仍然使用 px 做虚拟单位;
b. pt 是 iPhone 屏幕的专用单位,这里的 pt 就不再是 “磅” 或“点”了。
初代 iPhone 3GS 的对角线为 3.54inch,解析度为 320x480px,分辨率为 163ppi。Apple 将该机型的屏幕分辨率定义为基准分辨率,因此在该机型上 1px 图像会显示的长度就是 1/163inch,更丧心病狂的是,乔布斯将这个显示出来的 1/163inch 的长度定义为 1pt(我就是牛逼你能拿我怎么样),也是用了 pt 这个字母做长度单位,因此在基准分辨率下的 iPhone 屏幕上 1px=1/163in=1pt。(同理:安卓将初代安卓机型 160ppi 的屏幕上的 1/160inch 定义为 1dp),所以以后在给 iPhone 标注一倍图的时候不要再用 dp 和 px 了,你要打的过开发小鸽鸽也行。
px 是虚拟单位用来描述屏幕中图像的大小,是计算机识别单位,而 inch 是物理单位,用来描述人视线中的大小,只有在经过虚实匹配的标准电脑所显示的情况某种意义下才会保持数值一致(比如现在 pc 机的设置里有分辨率这一项,里面的推荐分辨率就是虚拟与现实一对一的像素对齐,讲到最后大家可以自己理解一下)
dp 与 px
为了保证相同的图片在不同分辨率的屏幕上显示的大小基本一致和清晰,微软、苹果、谷歌都提出了一个概念叫:与设备(密度)无关的像素(独立设备像素)Density(Device)- Independent Pixel,简称 DIP 或 DP,也叫逻辑像素。
仔细理解一下这句话 “与设备无关的像素”,首先可以知道 dp 也被叫做像素,似乎跟 px 差不多;然后说 “与设备无关”,这点就牛逼了,也就是说我不管在哪台设备上,不管是在 window 还是 MacOs 还是 iOS 还是 Android 的设备上,不管是大屏还是小屏,1dp 都是一样的长,你看到的那么长。例如在 iPhone 上用尺子量是 1cm 的一个图片,放到 pc 机上还是 1cm,要知道 iPhone 屏幕的精度是远高于 pc 机的好吧!
那这个单位是怎么想出来的呢?总不能就这么悬着没有一个标准吧!别急,且听老夫慢慢忽悠,我们下面会讲,这里需要大家记住 dp 的意义是:
“适配中控制变量,即保持最终显示图像的物理大小一致,dp 是人为定义的实际的物理单位。“,移动设备中,dp 和 pt 意义是一样的,只不过 dp 是安卓使用的,pt 是 iOS 使用的,下面还会讲。
所以先记住:pt、dp 和 px 是两种不同意义的单位,就像 “米” 和“个”。
sp 与 px
放大像素:Scaled Pixel 简称 sp,只用于描述字体的大小,基于基准分辨率来缩放的,也是一个中间单位,可以实现与 dp 一样的作用,但是其实质是不同的。(慢慢感受)
sp 是与缩放无关的抽象像素(Scale-independent Pixel)。sp 和 dp 很类似但唯一的区别是,Android 系统允许用户自定义文字尺寸大小(小、正常、大、超大等等),当文字尺寸是 “正常” 时,1sp=1dp=0.00625 英寸,而当文字尺寸是 “大” 或“超大”时,1sp>1dp=1 英寸 / 160dp=0.00625 英寸。类似我们在 windows 里调整字体尺寸以后的效果——窗口大小不变,只有文字大小改变。https://blog.csdn.net/aa971644/article/details/77583961 就是说如果你字体使用 dp 做单位的话,用户就不能再设置中自行把字体放大(老年人使用手机就得放大几号)
解析度 Resolution
米尺的分段数,例如:
长度为 1m 的尺子平均分成 10 段,解析度就是 10 段;
1㎡的木板平均分成 100 格,解析度就是 100 格 ////(懵逼了吧!)
同理:我们常说 iPhone8 的屏幕分辨率为 750x1334px,其实是指,iPhone8 的屏幕解析度是 750x1334px 即 1000500px,是指屏幕像素的个数。(国内常把解析度和分辨率都叫做分辨率。现在分辨率的使用真的非常混乱,我们只好将错就错)
分辨率 (密度、精度)
复合单位,解析度的倒数,也指单位刻度的长度,例如:
1m 的尺子平均分成 10 段,分辨率就是 10 段 / m,即每段 0.1m;
2m 的尺子平均分成 10 段,分辨率就是 5 段 / m,即每段 0.2m;
1㎡的木板平均分成 100 格,分辨率就是 100 格 /㎡ ,即每格 0.01㎡////(懵逼了吧!)
屏幕分辨率(Pixel density),即屏幕像素密度:Pixel Per Inch 简称 ppi(打印分辨率:Dot Per Inch 简称 dpi),**为了不与现在的广泛说法冲突,下面的分辨率全称为屏幕像素密度。**
屏幕上单位长度所含像素个数,想表达的是屏幕的显示精度,是联通现实与虚拟的桥梁,为什么不是单位面积内的像素数呢?因为算面积数值太大容易出错还很麻烦。
我们常说 iPhone8 的分辨率为:326ppi,指的是,iPhone8 屏幕上每英寸分布约有 326 个像素点。
算法:计算屏幕对角线上像素的数量
简单来写就是:ppi=px/in
why?
为什么屏幕大小以对角线长度为标准? - 知乎 https://www.zhihu.com/question/19640648
我的理解
1、为了屏幕多样性,这样屏幕长款是不受限制的,不然都做成方屏多简单;
2、前面提到像素点不一定就是方形的,反而不同尺寸的矩形子像素可以更好的将三原色平均分布到屏幕中,例如上面的 AMOLED 屏,因此造成长度上的分辨率和宽度上的分辨率不一致,两个数值都不能来描述屏幕像素密度,只有权重均值的对角线可以担此大任。
3、下面讲到的适配关系式也有助于理解。
英寸:inch
1inch=2.54cm 物理单位,用于有描述屏幕物理尺寸
为什么显示屏的大小用英寸而不是厘米衡量? - 知乎 https://www.zhihu.com/question/20452297
二、原理剖析
1、设备无关像素:与设备或密度无关的像素(Density(Device)- Independent Pixel,简称 DIP 或者 DP)
上面我们提到 dp 的意义是:
“适配中控制变量,即保持最终显示图像的物理大小一致,dp 是人为定义的实际的物理单位。“
那么该问题主要解决同一幅图像在不同大小的屏幕上看起来一样大的问题。我们先说原理后举例(放大招了)
如上图:假设有两台不同屏幕大小和屏幕像素密度的手机 A 与 B,屏幕像素密度分别是 Appi 与 Bppi,显示出了同样大小的图片(边长为μin 的正方形),
设图像在 A 手机中的边长为 apx,B 手机中的边长为 bpx,(注意:这里就是体现 px 这个虚拟单位意义的时候,它指的是手机识别的图片大小,到后面你会知道这个值就是你为不同手机做设计时所需要的尺寸)
先称述一个事实;
根据:ppi=px/in 可得出如下关系式:
apx/Appi=bpx/Bppi=μin ,变形可得:b/a=B/A,这里 B/A 就是两设备屏幕分辨率的比值α,
如果已知 A 手机中的图片大小 a,就可以知道 B 手机中图片的大小 b=a(B/A) ∴ b=aα
这个事实其实已经解决了屏幕倍率的问题。如果我们知道两台设备的分辨率(上他的官网查找),和其中一台设备屏幕设计稿的大小,就可以确定另一台屏幕应该采用多大的设计稿。
例如:iphone3GS 的屏幕像素密度为 163ppi,iphone8 的屏幕像素密度为 326ppi,∴α=326/163=2,在 3GS 上有一个 100px 的方形按钮需要适配到 iPhone8 上,那么给 iPhone8 的设计尺寸就应该是 100α=200,所以α就是我们说的倍率,
重点来了,上面我们已经提到
苹果将分辨率为 163ppi 的屏幕分辨率定为基准分辨率,即,在 163ppi 的屏幕中,1px=1pt=1/163in,
安卓将分辨率为 160ppi 的屏幕分辨率定为基准分辨率,即,在 160ppi 的屏幕中,1px=1dp=1/160in,
所以公式:b=a(B/A) 就是核心原理了,变成我们需要的单位就是:PXb=DP(PPIb/PPIa),PPIb/PPIa 就是屏幕间的倍率。
运用一下:
1:已知 iPhone8 的屏幕解析度是 750x1334px,那逻辑像素是多少?
答:因为 iphone8 的屏幕像素密度是 326ppi,是基准屏幕像素密度 163ppi 的两倍,所以逻辑像素 = 屏幕解析度➗2,最后得出逻辑像素是:375x667pt
2:已知 Huawei P20 的屏幕解析度为 2248x1080px,屏幕尺寸为 5.8inch,求屏幕宽度的逻辑像素是多少?
安卓并没有严格按照像素密度比例来作为倍率,而是规定了不同范围的密度属于何种倍率。
答:先根据屏幕像素密度计算方式,求得屏幕像素密度为 430ppi(实际为 428ppi,因为有刘海),参考安卓屏幕像素密度区间划分可知,该屏幕属于 3 倍屏 XXHDPI,所以,该机型宽度的逻辑像素 = 1080/3=360dp。
OK,到这里 pt 和 dp 就完全具备了实际的物理意义,都叫做与设备无关的逻辑像素,二者的实际长度不一样,但是谈两者的长度没有意义,只能说明两家的第一代手机苹果的比安卓的分辨率高一点点而已,我们说了 dp 是与设备无关的像素,并不影响屏幕图像的清晰度,所以不要在意 pt 和 dp 的具体长度,除非有一天你建立了自己的移动系统帝国,你定为 1/10000in 都没关系,只要你不嫌麻烦。
_插一段:_有同学就问了,你不是说 px 是虚拟单位,dp 是物理单位,两者不能混谈吗?是的,两者确实意义不一样,但是你要知道,px 是可以看的见数的清的数量单位,而 dp 是人为约定的单位,就像为什么 1m 就是 1m 那么长,在 m 诞生前是没有衡量标准,同样,kg 也是人为定义的质量单位,千克是一个实实在在的金属块,百年前科学家做了一块可以放置很久不会产生质量变化的金属玻璃罩内,以他的质量为标准定位 1kg,直至今日仍然放在各国博物馆内,每年都会有人专门去测量该物体的质量是否发生了变化(已经确定该金属质量已经低于最初的数值),他决定着所有物体的质量数值变化(现在科学家识图采用量子技术重新定义各种基本单位,例如銫原子钟可保一秒的时间几亿年都不会变),同样谷歌公司这样约定在 160ppi 的屏幕上的 1 个像素长度就是 1dp,1dp=1/160in。明白了吗?(呼,费劲)所以不要死磕为什么要这样定,我就这么定了你管得着吗?
回顾一下:
这就是屏幕的适配原理,嗯就酱,简单吧!
三、屏幕分辨率和系统分辨率如何影响图片的显示(装逼部分)
大家一定在 windows 系统上体验过这两个选项
根据我的理解:
第一个框 “更改文本、应用等项目的大小” 是系统分辨率(windows 默认 96ppi)
第二个框 “分辨率” 是模拟不同机型的屏幕解析度
讲一下(呱唧呱唧):
电脑在屏幕输出图像需要经过几个过程(纯属个人臆想):
计算机摄入图片,系统解析图像像素数据(像素数、色值等),系统将解析出的图片像素分发到屏幕中的像素点,最终屏幕呈现解析效果
所以这里有两个名词:系统分辨率和屏幕像素密度。
屏幕像素密度就是屏幕上的像素颗粒密度,而系统分辨率则是各系统自行规定的数值(其实就是逻辑分辨率),例如 windows 系统系统分辨率默认为 96ppi,Mac 系统默认系统分辨率为 72ppi,不受任何物理因素的影响,完全是虚拟量。一开始上面在讲 pt 与 px 的时候已经提到了这一点,与当时的市场环境有关
假设有一台显示器屏幕中显示图片:
屏幕尺寸:Sin
屏幕解析度:Rpx
屏幕像素密度:Pdpi
图片像素大小:npx
图片显示大小:Fin
则有:
Pdpi= Rpx / Sin (屏幕解析度对屏幕像素密度的影响)
Fin= npx / Pdpi (图片显示大小得出公式)
∴ Fin= npx / (Rpx / Sin)
= (npx Sin) / Rpx
综上所述:当屏幕尺寸不变,屏幕解析度缩小时,屏幕显示的图像会放大,所对应的就是上图中的 “分辨率”,只不过,这里的“分辨率” 是系统模拟不同机型的屏幕解析度。
如何引入系统分辨率?系统分辨率是用来解析电脑语言的,例如电脑不知道 1pt 有多长,但是他可以决定在在这个长度上安排多少个像素,所以,我们将上面的图片改为文字(因为文字是用磅来计量的),通过系统的解析将系统分辨率带入函数。如下
系统分辨率:sdpi
文字显示大小:Fin
文字输入大小:Npt(point)
文字像素大小:npx
则有:
npx=(Npt / 72)sdpi (求出了文字的像素大小)
∴ Fin= (npx Sin) / Rpx
= (Npt sdpi Sin) / (72Rpx)
综上所述:当屏幕尺寸和解析度不变的情况下,系统分辨率越大,显示的图像越大,所对应的就是上面的缩放百分比。怎么理解,系统分辨率越高意味着可以将同一幅图像拆分成更多个像素点,比如,72ppi 的系统分辨率解析 1pt 的文字,可以解析成 1x1 个像素点,那 144ppi 的系统分辨率就可把 1pt 的文字解析成 2x2 个像素点,因此提高后,同一幅图像占用了更多的像素点,即占用了更大的显示面积。所以显示的图像越大。
举个栗子🌰:
我有一台屏幕解析度为 1600x1200px 的显示器,想调成 800x600 的解析度,有两种办法:
1、调整设置中的 “分辨率” 为 800x600px,这样,图像会用当前的屏幕像素一对一显示 800x600 的图像像素(现在的显示器会放大到屏幕最大高度,单击游戏设置中可以体验小屏视窗),图像缩小居中于屏幕显示出来;
2、调整 “缩放” 为 200%,意味着系统分辨率提高了两倍,图像相应的放大了两倍,这种效果跟前一种的情况把显示区域放大到完整屏幕的效果是一致的,也就是仿真显示。
大概就这些,基本都逼逼完了,不知道大家可以理解多少。以上内容不具有专业性,本人也并非技术人员,如果有不正确的地方欢迎指出,彼此共勉。
感谢