关于 dp dip dpi ppi px sp 你应该知道的一切

文章来自:

PX(pixel 像素)

px 也叫像素点,是屏幕物理上的最小显示单位,如手机分辨率 1080 x 1920 表示宽有 1080 像素点,高有 1920 像素点。像素的大小是没有固定长度的,不同设备上一个单位像素色块的大小是不一样的。尺寸面积大小相同的两块屏幕,分辨率大小可以是不一样的,分辨率高的屏幕上面像素点(色块)就多,所以屏幕内可以展示的画面就更细致,单个色块面积更小,而分辨率低的屏幕上像素点(色块)更少,单个像素面积更大,可以显示的画面就没那么细致。

dpi(dots per inch)

dpi也被称为屏幕密度,就是每英寸所打印的点数。实际上dpi的计算是通过勾股定理算出屏幕对角的像素数再除以对角的尺寸就是最终的dpi。以一台的机器为例:

  • 尺寸:6.0英寸(一般所说的尺寸就是机器的对角线尺寸。)
  • 分辨率:1080*1920
    那么dpi算法则为1080的平方加上2160的平方再开方约等于2203。再用2203除以6得到约367。则367dpi为该机器的像素密度。

ppi(pixels per inch)

ppi和dpi这两个措辞的差别,表面上看来只在于是在谈 dot,还是 pixel,但实际上 dot 可以打印的墨点,可以指扫描仪的采样点,可以指数字图像的最小单位(即 pixel),可以指屏幕的物理像素,可以指操作系统的抽象像素……在不同的语境下可以指不同的概念,而同样 pixel 也可以指数字图像的数据 pixel,可以指屏幕物理像素,也可以指代操作系统的抽象像素……在不同语境下的意义也不同。这两个单位完全就是时常混用的,在电子屏幕显示中提到的 ppi 和 dpi 可以认为是一样的,所以你可以忽略在措辞上用 dpi 或者 ppi 有什么不同,不过在 Android 平台上常用 dpi 这种表述方式。

dp/dip(device independent pixels)

dp也称设备独立像素,dp和dip是同一个概念,都是device independent pixels的简称。举个例子:
宽2英寸,长3英寸的屏幕上,如果将一个控件的宽度设为160px,则会出现如下的情况:

  • 屏幕分辨率宽度为320px,则该控件占据屏幕宽度一半。
  • 屏幕分辨率宽度为640px,则该控件占据屏幕宽度的四分之一。
    这十分影响体验。所以Android引入了设备独立像素的概念,也就是dp这种单位。首先Android规定在160dpi的设备上1dp=1px,当屏幕密度为320dpi时,1dp=2px,以此类推。。。正式如此,我们得以保证控件在不同屏幕密度上显示一致,从而完成屏幕适配。回到上面的例子,当我们使用新的单位dp时,当将控件的宽度设为160dp:
  • 在分辨率为 320 x 480(既 dpi 为 160)的屏幕上,则 160dp 等价于 160px,控件占屏幕宽的一半;
    在分辨率为 640 x 960(既 dpi 为 320)的屏幕上,则 160dp 等价于 320px,控件依然占屏幕宽的一半,就解决大小比例不一致的问题。
    下面是网上常用的 dp 和 px 之间转换的工具类:
public static int dp2px(Context context, int values) {
  float scale = context.getResources().getDisplayMetrics().density;
  return (int) (values * scale + 0.5f);
}

public static int px2dip(Context context, float pxValue) {
  float scale = context.getResources().getDisplayMetrics().density;
  return (int) (pxValue / scale + 0.5f);
 }
//+0.5 就是为了在精度丢失的情况下进行四舍五入。

drawable 目录加载和 dpi 间的关系

说到 dpi 这里就不得不联想到在 Android 工程里 res 目录下的 drawable-hdpi, drawable-xhdpi, drawable-xxhdpi 等文件夹。我们知道 Android 会根据屏幕的 dpi 去选择对应的 drawable 文件夹,Android项目的资源文件下存在以下目录:

  • drawable-ldpi ( 当dpi为120时,使用此目录下的资源)
  • drawable-mdpi ( 当dpi为160时,使用此目录下的资源)
  • drawable-hdpi ( 当dpi为240时,使用此目录下的资源)
  • drawable-xhdpi ( 当dpi为320时,使用此目录下的资源)
  • drawable-xxhdpi ( 当dpi为480时,使用此目录下的资源)
  • drawable-xxxhdpi ( 当dpi为640时,使用此目录下的资源)

Android 正是根据设备DPI值得不同,选择清晰度不同的资源使用,完成屏幕的适配, 可以看出系数比例关系:0.75:1:1.5:2:3:4,但手机屏幕千奇百怪,例如如果一个手机屏幕是 420 dpi 不属于上述文件分类中的任何一个,因此上述文件夹不是指定具体的分辨率,而是一个范围:

  • drawable-ldpi(value <= 120 dpi)
  • drawable-mdpi(120 dpi < value <= 160 dpi)
  • drawable-hdpi(160 dpi < value <= 240 dpi)
  • drawable-xhdpi(240 dpi < value <= 320 dpi)
  • drawable-xxhdpi(320 dpi < value <= 480 dpi)
  • drawable-xxxhdpi(480 dpi < value <= 640 dpi)

以此类推,所以 420 dpi 会优先加载 xxdpi 中的资源文件,如果对应 dpi 目录下没有找到该资源文件,遵循先高再低原则,然后按比例缩放图片,比如当前为 xhdpi 设备,则 drawable 的寻找顺序为:
xhdpi -> xxhdpi -> xxxhdpi (如果没有更高的了) -> nodpi (如果有的话) -> hdpi -> mdpi,如果在 xxhdpi 中找到目标图片,则压缩 2/3 来使用,如果在 mdpi 中找到图片,则放大 2 倍来使用。

sp(scalable pixels)

最后来说一说 sp,sp 与缩放无关的像素单位,类似 dp ,不同之处在于它还会根据用户字体大小配置而缩放。所以开发中指定字体大小时建议使用 sp ,因为 sp 作为字体大小单位会随着系统的字体大小改变,下面是 sp 和 px 之间转换工具类:

public static int px2sp(Context context, float pxValue) {  
  float fontScale = context.getResources().getDisplayMetrics().scaledDensity;  
  return (int) (pxValue / fontScale + 0.5f);  
}  

public static int sp2px(Context context, float spValue) {  
  final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;  
  return (int) (spValue * fontScale + 0.5f);  
}

从代码中也可以看出 sp 和 px 间转换使用的是 scaledDensity,而 dp 和 px 间转换使用的是 density,也就是 sp 会随着系统字体设置缩放,dp 不会。

一般UI拿过来的图就是px标注的,然后会告诉你做图时所用的尺寸是多大的,如1334x750,4.7寸的屏幕
image
  1. 计算UI给出的图纸屏幕的dpi:
1334*1344+750*750=2342056
2342056开方约等于1530
1530/4.7=325dpi
  1. 所以在325dpi下为80px,在标准的160dpi的计算为:
80 * 160 / 325 约等于40px。

在160dpi的像素为40px,所以设置为40dp。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351

推荐阅读更多精彩内容