完全理解px,dpr,dpi,dip

写在前面

从media query一路摸过来,花了大把时间才弄明白这些东西的含义

设备像素

设备像素(Device Pixels):设备屏幕的物理像素,单位是px,比如iPhone6的750x1334px

P.S.表示屏幕上可以铺多少个点点,而不是一个绝对长度单位(例如in,mm),因为我的点点和你的点点大小不一样

分辨率

分辨率(Resolution)也是一个物理概念,含义要看对谁

对于屏幕,分辨率一般表示屏幕上显示的物理像素总和。比如,我们说iPhone6屏幕分辨率是750x1334px

对于图像,概念等同于图像尺寸、图像大小、像素尺寸等等。比如,我们说20x20px的icon

P.S.其实严格来说,图像分辨率的单位是ppi(Pixels Per Inch),对于一个图片文件,其像素尺寸是一定的,可能含有来自相机的meta信息,比如分辨率200ppi,该值只是个建议值,图片显示出来我们看到的尺寸由屏幕像素密度决定,像素密度越高,图片看起来越小

CSS像素

CSS像素(CSS Pixels):是Web编程的概念,指的是CSS样式代码中使用的逻辑像素

所以,1个CSS像素在不同设备上可能对应不同的物理像素数,这个比值是设备的属性(Device Pixel Ratio,设备像素比)

在CSS规范中,长度单位可以分为绝对单位和相对单位。px是一个相对单位,相对的是设备像素(Device Pixels)。比如iPhone5使用的是Retina视网膜屏幕,用2x2的Device Pixel代表1x1的CSS Pixel,所以设备像素数为640x1136px,而CSS逻辑像素数为320x568px

设备像素比

设备像素比缩写为DPR或者DPPX,如下:

  • Device Pixel Ratio: Number of device pixels per CSS Pixel

  • Dots Per Pixel: the amount of device pixels per CSS pixel (e.g. in Retina displays this will be 2).

一般我们说DPR,wiki定义:

Device pixel ratio, the ratio between physical pixels and logical pixels used by cascading style sheets (CSS): other names for it are “CSS Pixel Ratio” and “dppx”

所以,设备像素比表示1个CSS像素(宽度)等于几个物理像素(宽度):

DPR = 物理像素数 / 逻辑像素数

比如dpr=2时,1个CSS像素由4个物理像素点组成,见上面对CSS像素的解释

P.S.DPR不是单位,而是一个属性名,比如在浏览器中通过window.devicePixelRatio获取屏幕的DPR

特别注意:zxx的说法:

window.devicePixelRatio是设备上物理像素和设备独立像素(device-independent pixels (dips))的比例。

公式表示就是:window.devicePixelRatio = 物理像素 / dips

这里的“设备独立像素”,指的就是逻辑像素,即CSS像素,也是一个属性名,不要和Android的单位dip/dp弄混了,二者没有任何关系,虽然英文一样,含义也差不多,但那是Android自家的事情,不通用

像素密度

像素密度也叫显示密度或者屏幕密度,缩写为DPI(Dots Per Inch)或者PPI(Pixel Per Inch),含义相同

专业的一般说PPI,细微差异如下:

ppi和dpi(每英寸点数)。从技术角度说,“像素”(p)只存在于计算机显示领域,而“点”(d)只出现于打印或印刷领域。

经常看到相同尺寸的屏幕像素尺寸却不同,也就是DPI的差异,比如4.7英寸的iPhone6像素尺寸为750x1334px,而4.7英寸的HTC One像素尺寸为1080x1920px

像素密度很容易算出来,比如iPhone6的:

// 屏幕对角线的像素尺寸 / 物理尺寸(inch)
Math.sqrt(750*750 + 1334*1334) / 4.7 = 326ppi

生活案例:

Windows设置分辨率修改的应该就是像素密度(像素密度是一个属性,固定不变,因为屏幕物理像素尺寸和物理尺寸都是固定的)设备像素比,所以同一张图片在不同分辨率设备上的显示尺寸不同,像素设备像素比越低,逻辑分辨率越高(dpr=1时逻辑分辨率=物理分辨率),图片显示尺寸越小(用尺子量屏幕),比如Windows 1920x1080分辨率下桌面图标/字体都比1366x768下要小些。而图片浏览工具能放大一张图片,实际上是通过软件插值模拟像素数据增加了宽高像素数量,所以放很大时会不清晰(失真),缩小也存在这样的问题

在输出的最后时刻:比如显示、或打 印、或冲印时的DPI设置,才是最后决定输出尺寸大小的关键设置,机身形成文件所标示的什么180DPI72DPI都只是一种设定好的临时参数。所以洗照片可以有寸照、2寸照等等

相机中EXIF显示的DPI或者photoshop中显示的DPI只是相机随便假设你的最终输出的对象的一个数据,因为相机和PS都不知道你最终用的打印机是什么DPI,也不知道你是不是就是为了放在网络上,所以就随便假设了一个数,其实没有任何的意义

设备独立像素

一般指Google提出的用来适配Android海量奇怪屏幕的,Windows也有这个概念,但含义不同,IOS好像没有设备独立像素一说

设备独立像素作为单位,一般是指Android开发中的东西,缩写为DIP(Device Independent Pixels)或者DP(Density-independent Pixels),含义完全一致

Android设备的特点是屏幕尺寸很多,因此为了显示能尽量和设备无关,提出了dip,参照的density是160。计算公式为:

// 当屏幕密度为160(单位是ppi或者dpi,一个意思)时,px === dip
px = dip * density / 160 
// 所以
dip = px * 160 / dpi

当然,则两个式子都只适用于Android设备,这个dip拿到其它地方去没什么意义

视口(viewport)

桌面上视口宽度等于浏览器宽度,但在手机上有所不同。

  • 布局视口

    手机上为了容纳为桌面浏览器设计的网站,默认布局视口宽度远大于屏幕宽度,为了让用户看到网站全貌,它会缩小网站

  • 视觉视口

    屏幕的可视区域,即物理像素尺寸

  • 理想视口

    当网站是为手机准备的时候使用。通过meta来声明。早期iPhone理想视口为320x480px

所以,在没有缩放的情况下,屏幕的CSS像素宽度其实是指理想视口的宽度,而meta标签:

<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/>

指定了布局视口=理想视口,并且禁止缩放。所以添上width=device-width的viewport meta后页面变大了(一开始页面内容小得看不清),实际上是布局视口变小了

参考资料

完全理解px,dpr,dpi,dip》上有7条评论

  1. 酸梅先生

    我有一个疑问

    iphone3GS,4,5,6 的 dpi 也就是逻辑像素密度都是163,也就是说每一英寸有163个逻辑像素点,iphone6Plus的逻辑像素密度是154,也就是说每一英寸有154个逻辑像素点。 iphone6Plus中每个逻辑像素点都变大了,如果“逻辑像素即CSS像素”,那岂不是CSS像素也变大了,那同样的100px的一条线在iphone6Plus中岂不是要比在iphone6中长6%

    万望解惑

    回复
    1. ayqy 文章作者

      dpi的话,3GS 163, 4567/S/C/E 326, 67S/SP 401http://dpi.lv/

      没有逻辑像素密度这个概念

      像素密度/生活案例

      像素密度是一个属性,固定不变,因为屏幕物理像素尺寸和物理尺寸都是固定的

      例如3.5英寸的iPhone4 326dpi,表示屏幕上每英寸有326个物理像素点,计算方法就是对角线的像素尺寸除以对角线的物理尺寸Math.sqrt(640 * 640 + 960 * 960) / 3.5 = 329.65

      像素尺寸是640 x 960,DPR(设备像素比)是2,那么CSS像素尺寸就是320 x 480,一个CSS像素等于4个物理像素

      3GS上的100px和4上的100px线,非要比较长短的话,要统一度量单位,比如用物理像素数,分别是100和200,用物理尺寸的话,一样长。

      回复
      1. 酸梅先生

        逻辑像素密度就是常说的逻辑点密度。讨论的不是iphone3G与iphone4。iphone6及之前的手机dpi都是一样的。 我实际验证了一下,iphone6Plus的1个逻辑点就是比iphone6的大,这也是苹果有意为之。

        回复
  2. xyang1000

    DPR = 物理像素数 / dips

    这里虽然 Windows 把它叫做 Device pixel,但我认为它就是根据 DPI/Density 这一类参数调整后输出显示的 pixel。

    iOS 将 iPhone 6/7/8 Plus 的 DPI 参数设置为 480 而不是与真实的 PPI 401 相同,于是输出分辨率为12422208,与物理分辨率(device pixel)19201080 不同。 相当一部分 安卓手机 出厂就将 DPI 参数调整得跟 PPI 不一样,而用户 Root 后也可以修改 DPI 改变输出显示的分辨率 可能这就反过来说明了 iOS 和 安卓 给第三方的权限都仅限于接触到DPI/Density参数,接触不到设备真实的 PPI,即只能接触到渲染输出后的分辨率,而不是设备原本的物理分辨率。

    所以我猜测 Windows 也是一样的,如果我将电脑的 Windows 的输出分辨率从推荐的也就是和设备物理分辨率相等的19201080调到1600900,「DPR = 物理像素数 / dips」中的物理像素指的应该是 1600*900 这个显示像素中的像素

    PS: PPI 和 DPI 不同的情况太多了,PPI 对应的 device pixel 和 DPI 对应的 pixel 严格区分还是有必要的

    回复

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*

code