像素相关知识整理:px/pt/dp/sp/ppi/dpi……

皮酱叨逼叨

共 5239字,需浏览 11分钟

 ·

2021-04-09 22:06

前言

此文的的内容全部收集自网上,来源太多,所以不太方便注明出处了,但是基本上的概念我都自己梳理了一遍,避免出现太多错误。

分享此文是因为这段时间在做安卓APP的产品设计,然后发现自己对这一块的知识并不熟悉,而且在网上找到信息也是参差不齐,漏洞百出。于是我花了点时间,将一些写得不错,表达的比较准确的文章的内容摘录了下来,整理成了此文。

其中最难懂或者争议性最大的部分是设备像素比DPR和倍率那一节,找资料和核对校验花费了60%以上的时间。如果怕绕晕或者不想了解那么细节的内容,这一部分可以选择性跳过,只需要了解其他简单的科普知识即可。

名词解释

px:pixel(像素),是屏幕上显示数据的最基本的点,单个像素没有具体的尺寸概念。相同尺寸的显示器下,像素越多,单个像素的尺寸就越小,屏幕越清晰;像素越少,单个像素的尺寸就越大,屏幕越模糊。例如都是14寸的1080P和4K的笔记本电脑屏幕对比,明显是4K屏幕更清晰,更细腻。

pt:point(点),有两种含义,第一种是来自于印刷行业,它是绝对长度单位,1pt=1/72英寸,约等于0.35毫米,有些软件中称为磅;另一种就是作为iOS开发中的最小开发长度单位,1pt表示屏幕像素点密度为163ppi时,1px的长度。

PPI:屏幕像素密度,即每英寸(长度)所包含的像素点数,该值越高,则屏幕越细腻;除了用勾股定理来计算,直接用长的像素/长(英寸),或者宽的像素/宽(英寸)也可以。
DPI:DPI(Dots Per Inch,每英寸点数)是一个量度单位,用于点阵数码影像,指每一英寸长度中,取样、可显示或输出点的数目。DPI这个单位中的「dot」一般也翻译为「点」,但此点(dot)非彼点(point)。Dot 指的是采样或输出的最小单位,它很抽象,在不同的设备里会和不同的具体事物关联起来;在目前越来越多的数码设备的情况下,有时大家也会用用 DPI来描述显示器,dot 就是显示器的物理像素(实际的像素)。
所有在很多场景下,PPI基本等同于DPI,但是用来描述屏幕的分辨率尽量用PPI较为标准一些,可以参考APPLE官网上手机的数据。


dp:安卓开发中的最小长度单位,1dp表示在屏幕像素点密度为160PPI时1px长度;属于一个绝对单位,公式有px=dp*(DPI/160),所以安卓手机密度(DPI)越高,1pd对应的像素px就会越大。安卓中比较喜欢用DPI,iOS中比较喜欢用PPI。

sp :安卓的字体单位,和dp类似,表示当屏幕像素密度为160ppi,且字体大小为100%时,1sp=1px。也是一个绝对单位,解释同上。

英寸:英寸和毫米都是长度单位,可以直接测量 ,1 inch=25.4 mm。

分辨率:分辨率,又称解析度、解像度,可以细分为显示分辨率、图像分辨率、打印分辨率和扫描分辨率等。描述分辨率的单位有:DPI(点每英寸)、LPI(线每英寸)、PPI(像素每英寸)和PPD(PPPixels Per Degree 角分辨率,像素每度)。

屏幕密度:属于安卓开发中自创的一个词,也叫做像素密度。是屏幕单位面积内的像素数,称为 dpi(每英寸的点数)。它与分辨率不同,后者是屏幕上的总像素数。
这个地方有点像是安卓故意自成一套体系,然后搞的密度,PPI,DPI混乱的很。其实屏幕密度就是我们俗称的DPI,也可以理解成PPI,用来表示单位面积内容像素数量的多少……


网传的一些误区或者不准的

1. 1pt=1/72inch

在印刷排版中,“point”是一个绝对的单位,它等于 1/72 英寸,可以用尺子丈量的,物理的英寸;在iOS中,这里的point是一个绝对单位。苹果人为规定在非retina屏幕上(320*480px),1pt = 1px。web中的pt和ios原生开发中的pt含义不一样,web中的1pt=1/72英寸,12pt字体=16px字体。

所以很多人在科普的时候会说1pt=1/72inch,这个是准确的,也可以说是不准确的,主要是要看具体的语境。一般如果用来表达iOS的UI设计的时候,那么说1pt=1/72inch就是不准确的,应该是指非retina屏幕上(320*480px),1pt = 1px。


2. DPI和PPI乱用

DPI(Dots Per Inch,每英寸点数)是一个量度单位,用于点阵数码影像,指每一英寸长度中,取样、可显示或输出点的数目。

PPI 是英文 Pixels Per Inch 的缩写,意味每寸能容纳多少颗像素,用于描述屏幕的像素密度。

关于「DPI」与「PPI」这一对常用单位:「DPI(dots per inch)」描述的是每英寸有多少个采样点;而「PPI(pixels per inch)」描述的是每英寸有多少个像素。因为对于数字图片来说,采样点就是像素,于是在电脑里 DPI 和 PPI 经常混用,这造成了一些混淆,但它们的目的都是把虚拟的点/像素和实际的尺寸联系起来(比如我们常用 72 PPI、326 PPI)。

从我找资料的场景来看,我初步得出一个结论:安卓中比较喜欢用DPI,iOS中比较喜欢用PPI,大多数场景下,这两者是同一回事。


3. 设备像素(DP)和设备独立像素(DIP)

设备像素又称物理像素,其尺寸大小是不会变的,从显示屏从工厂出来的那刻起,物理像素点就不会变了。
例如iPhone 6 的分辨率是750 x 1334 ,那么这个 750 就是代表 750 的物理像素,是从手机出厂的那刻起,就不会变了,750 表示的就是手机的宽是 750px。这个应该比较好理解。

设备独立像素又称逻辑像素(也叫密度无关像素),其尺寸大小是相对的。可以认为是计算机坐标系统中的一个点,这个点代表一个可以由程序使用的虚拟像素(比如:CSS像素),然后由相关系统转换为物理像素。一般指Google提出的用来适配Android海量奇怪屏幕的,Windows也有这个概念,但含义不同,iOS好像没有设备独立像素一说。


设备独立像素是一个整体概念,包括了CSS像素。只是在Android 机中,CSS像素不叫 「CSS像素了,而叫「设备独立像素所以Android中的DIP和Windows中的其实表示的含义不太一样,不过大多数场景下可以近似理解为同一个东西。


打开Chrome浏览器的F12,改成手机设备模式,可以查看到iPhone6/7/8的设备独立像素(逻辑像素)是375*667,但是实际的设备像素(物理像素)是1334*750。


4. 设备像素比DPR和倍率(可跳过)

设备像素比 DPR(devicePixelRatio) 是默认缩放为100%的情况下,设备像素和CSS像素的比值。DPR=设备像素/设备独立像素(是在同一个方向,一维的)。

设备像素比(简称dpr)定义了物理像素和设备独立像素的对应关系,是设备上物理像素和设备独立像素(device-independent pixels (dips))的比例,它的值可以按如下的公式的得到:
设备像素比 = 物理像素 / 设备独立像素 // 在某一方向上,x方向或者y方向

还可以通过window.devicePixelRatio获取到当前设备的dpr,上图中就算出来了iPhone6/7/8的DPR大约是2。
window.devicePixelRatio
这个是浏览器的命令,和iOS还有Android的获取方式不太一样,但是浏览器应该是做了对应的数据兼容的。所以在F12中,通过这个输出的DPR,和安卓的密度倍数或iOS的比例因子是相同的。例如iPhone6/7/8的DPR大约是2,比例因子(scale)也是2。

倍率一般常见于一些UI切图的文章中,用来通俗的描述当前设备的设备像素(物理像素)与设备独立像素(逻辑像素)之间的比值(DPR),例如常见的iOS中的@2x,@3x,安卓中的mdpi,hdpi,xhdpi,xxhdpi等。


Android设备的特点是屏幕尺寸很多,因此为了显示能尽量和设备无关,提出了设备独立像素(dp),它作为单位,一般特指Android开发中的单位,缩写为dip(Device Independent Pixels)或者dp(Density-independent Pixels)。

参照的density(屏幕密度)是160。计算公式为:
px = dp * density / 160
所以
dp = px * 160 / dpi
安卓规定屏幕PPI为160时,1pt=1px,我们只需要看屏幕PPI和160的比值即可,这个就是常看到的倍率的计算方法。
所以安卓设备是从density来判断屏幕的密度属于哪个档位,获取density的方法是:
DisplayMetrics metrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
metrics.density; 3.5
metrics.densityDpi; 560

iOS规定屏幕PPI为163时,1pt=1px,此时用1倍图,我们只需要看iOS手机屏幕的ppi和163的比值就行了。但是也有某些情况下特殊(iPhone 6+/7+/8+),所以最准确的其实还是要通过代码来获取设备像素比DPR,这个值在iOS中也叫做比例因子(scale),也就是我们常说的倍率。

iOS获取比例因子的方式是:
//1、得到当前屏幕的尺寸:
CGRect rect_screen = [[UIScreen mainScreen] bounds];
CGSize size_screen = rect_screen.size;
//2、获得scale:iPhone5和iPhone6是2,iPhone6Plus是3
CGFloat scale_screen = [UIScreen mainScreen].scale;
NSLog(@"scale_screen:%.f", scale_screen);
//3.获取当前屏幕的分辨率
CGFloat widthResolution = size_screen.width * scale_screen;
CGFloat heightResolution = size_screen.height * scale_screen;

实际应用

1. 原型绘制

知道了上述的一些背景知识之后,绘制原型的时候就可以有一定的针对性了。很早的时候我也以为绘制移动端的原型就按照物理像素来设计就好了,例如常见的1920*1080,但是显然这样画出来的原型太大了,并不好看。然后又想办法按Chrome上给的设备独立像素来绘制原型,但是iOS和安卓不同设备又不一样的宽高比例。可能自己不懂这一块就索性随意找了一个比例就开始画起来了,这样可能导致后续UI再重新设计的时候会有一些困扰。

如果团队中没有UI,直接将原型交付给开发的话估计要翻车,大概率还是要重新做一套的。

当前很多人会选择使用 375px 来作为移动端APP的设计宽度,然后基于这个比例来确定相应的组件高度和大小等。因为375px是一个1倍图的比例,可以兼容iOS也可以兼容Android,方便UI直接出设计稿,或者没有UI的时候开发可以直接参考比例来开发。

2. UI设计切图

很多时候产品可能自己也不太懂这一块的底层知识,而是自己用一个大概的比例绘制好了原型之后,交由给UI设计师进行精确化比例的绘制。所以一般来说,UI对这些基础知识会掌握的比较多一些,UI也必须要了解这些内容才能更好的确定准确的设计方案。

例如我们常说的,要输出几倍图,要怎么切图,要切几份等等,其实背后都是这些底层的知识做支撑。当然从目前的情况来看,网上已经有很多成品的数据了,如果不想了解那么多复杂的背景和原理等,那就直接找一个可信的数据模板按照对应的倍率直接设计即可,也不会错了。

3. 适配多种设备

上面提到了iOS和Android其实都有很多种类的设备,拥有不用的设备像素(物理像素),也有不同的设备独立像素(逻辑像素),所以UI稿需要兼容市面上的绝大多数的设备。

所以设计师在出图的时候,会根据屏幕PPI不同,需要输出了1倍/2倍/3倍图,并且分门别类放在不同的文件夹中。例如下图的安卓静态资源文件夹中放了不同倍率下的资源。
关于适配还有其他方面的一些细节,例如刘海屏适配,图片兼容性,间距比例的问题,但是我接触的也不是很多,所以在此不展开讲那么多了……





END



浏览 367
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报