Android 一个像素几个字节,android 像素单位的一系列疑问困扰

1、了解几个概念

(1)分辨率。分辨率就是手机屏幕的像素点数,一般描述成屏幕的“宽×高”,安卓手机屏幕常见的分辨率有480×800、720×1280、1080×1920等。720×1280表示此屏幕在宽度方向有720个像素,在高度方向有1280个像素。

(2)屏幕大小。屏幕大小是手机对角线的物理尺寸,以英寸(inch)为单位。比如某某手机为“5寸大屏手机”,就是指对角线的尺寸,5寸×2.54厘米/寸=12.7厘米。

(3)密度(dpi,dots per inch;或PPI,pixels per inch)。从英文顾名思义,就是每英寸的像素点数,数值越高当然显示越细腻。假如我们知道一部手机的分辨率是1080×1920,屏幕大小是5英寸,你能否算出此屏幕的密度呢?哈哈,中学的勾股定理派上用场啦!通过宽1080和高1920,根据勾股定理,我们得出对角线的像素数大约是2203,那么用2203除以5就是此屏幕的密度了,计算结果是440。440dpi的屏幕已经相当细腻了。

5f8deac31d1d

2、实际密度与系统密度

尚未发现他处使用“实际密度”和“系统密度”这两个词汇,暂时由我如此定义吧。

“实际密度”就是我们自己算出来的密度,这个密度代表了屏幕真实的细腻程度,如上述例子中的440dpi就是实际密度,说明这块屏幕每寸有440个像素。5英寸1080×1920的屏幕密度是440,而相同分辨率的4.5英寸屏幕密度是490。如此看来,屏幕密度将会出现很多数值,呈现严重的碎片化。而密度又是安卓屏幕将界面进行缩放显示的依据,那么安卓是如何适配这么多屏幕的呢?

其实,每部安卓手机屏幕都有一个初始的固定密度,这些数值是120、160、240、320、480,我们权且称为“系统密度”。大家发现规律没有?相隔数值之间是2倍的关系。一般情况下,240×320的屏幕是低密度120dpi,即ldpi;320×480的屏幕是中密度160dpi,即mdpi;480×800的屏幕是高密度240dpi,即hdpi;720×1280的屏幕是超高密度320dpi,即xhdpi;1080×1920的屏幕是超超高密度480dpi,即xxhdpi。

安卓对界面元素进行缩放的比例依据正是系统密度,而不是实际密度。

5f8deac31d1d

1496395208(1).jpg

5f8deac31d1d

算图片内存占用大小的实例应用

首先要明确图片占用内存和哪些参数有关系:

1:色彩格式,前面我们已经提到,如果是ARGB8888那么就是一个像素4个字节,如果是RGB565那就是2个字节

2:原始文件存放的资源目录(是hdpi还是xxhdpi可不能傻傻分不清楚哈)

3:目标屏幕的密度(所以同等条件下,红米在资源方面消耗的内存肯定是要小于三星S6的)

scaledWidth = int( 522 * 640 / 480f + 0.5) = int(696.5) = 696

(图片的Width*手机真实的密度/图片所在文件夹的系统密度+0.5)

scaledHeight = int( 686 * 640 / 480f + 0.5) = int(915.16666...) = 915

(图片的Height *手机真实的密度/图片所在文件夹的系统密度+0.5)

下面就是见证奇迹的时刻:

915 * 696 * 4 = 2547360

(图片的scaledWidth *图片的scaledHeight *色彩格式每个像素占用的字节数)=占用的系统内存

3、一个重要的单位dp

dp也可写为dip,即density-independent pixel。你可以想象dp更类似一个物理尺寸,比如一张宽和高均为100dp的图片在320×480和480×800的手机上“看起来”一样大。而实际上,它们的像素值并不一样。dp正是这样一个尺寸,不管这个屏幕的密度是多少,屏幕上相同dp大小的元素看起来始终差不多大。

另外,文字尺寸使用sp,即scale-independentpixel的缩写,这样,当你在系统设置里调节字号大小时,应用中的文字也会随之变大变小。

5f8deac31d1d

4、dp与px的转换

在安卓中,系统密度为160dpi的中密度手机屏幕为基准屏幕,即320×480的手机屏幕。在这个屏幕中,1dp=1px。

100dp在320×480(mdpi,160dpi)中是100px。那么100dp在480×800(hdpi,240dpi)的手机上是多少px呢?我们知道100dp在两个手机上看起来差不多大,根据160与240的比例关系,我们可以知道,在480×800中,100dp实际覆盖了150px。因此,如果你为mdpi手机提供了一张100px的图片,这张图片在hdpi手机上就会拉伸至150px,但是他们都是100dp。

中密度和高密度的缩放比例似乎可以不通过160dpi和240dpi计算,而通过320px和480px也可以算出。但是按照宽度计算缩放比例不适用于超高密度xhdpi和超超高密度xxhdpi了。即720×1280中1dp是多少px呢?如果用720/320,你会得出1dp=2.25px,实际这样算出来是不对的。dp与px的换算要以系统密度为准,720×1280的系统密度为320,320×480的系统密度为160,320/160=2,那么在720×1280中,1dp=2px。同理,在1080×1920中,1dp=3px。

大家可以记住下面这个比例,dp与px的换算就十分easy啦!

ldpi:mdpi:hdpi:xhdpi:xxhdpi=3:4:6:8:12,我们发现,相隔数字之间还是2倍的关系。计算的时候,以mdpi为基准。比如在720×1280(xhdpi)中,1dp等于多少px呢?mdpi是4,xhdpi是8,2倍的关系,即1dp=2px。反着计算更重要,比如你用PhotoShop在720×1280的画布中制作了界面效果图,两个元素的间距是20px,那要标注多少dp呢?2倍的关系,那就是10dp!

5f8deac31d1d

当安卓系统字号设为“普通”时,sp与px的尺寸换算和dp与px是一样的。比如某个文字大小在720×1280的PS画布中是24px,那么告诉工程师,这个文字大小是12sp。

概念解释

名词

解释

Px(Pixel像素)

不同设备显示效果相同。这里的“相同”是指像素数不会变,比如指定UI长度是100px,那不管分辨率是多少UI长度都是100px。也正是因为如此才造成了UI在小分辨率设备上被放大而失真,在大分辨率上被缩小。

ScreenSize(屏幕尺寸)

一般所说的手机屏幕大小如1.6英寸、1.9英寸、2.2英寸,都是指的对角线的长度,而不是手机面积。我们可以根据勾股定理获取手机的宽和长,当然还有面积。

Resolution(分辨率)

指手机屏幕垂直和水平方向上的像素个数。比如分辨率是480*320,则指设备垂直方向有480个像素点,水平方向有320个像素点。

Dpi(dots per inch像素密度)

指每英寸中的像素数。如160dpi指手机水平或垂直方向上每英寸距离有160个像素点。假定设备分辨率为320*240,屏幕长2英寸宽1.5英寸,dpi=320/2=240/1.5=160注意:该值对应于DisplayMetrics类中属性densityDpi的值。具体请参考http://www.cnblogs.com/wader2011/archive/2011/11/28/2266669.html

Density(密度)

指每平方英寸中的像素数。Density=Resolution/Screen size注意:在DisplayMetrics类中属性density的值为dpi/160,可用于px与dip的互相转换。具体请参考http://www.cnblogs.com/wader2011/archive/2011/11/28/2266684.html

Dip(Device-independent pixel,设备独立像素)

同dp,可作长度单位,不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA、HVGA和QVGA 推荐使用这个,不依赖像素。dip和具体像素值的对应公式是dip值 =设备密度/160* pixel值,可以看出在dpi(像素密度)为160dpi的设备上1px=1dip

Sp(ScaledPixels放大像素)

主要用于字体显示(best for textsize)。根据 google 的建议,TextView 的字号最好使用 sp 做单位,而且查看TextView的源码可知 Android 默认使用 sp 作为字号单位。

设备最终会以px作为长度单位展现在手机屏幕上,如果我们直接用px作为单位会造成UI在不同分辨率设备上出现不合适的缩放。因此我们需要一种新的单位,这种单位要最终能够以合适的系数换算成px使UI表现出合适的大小。所以dp就是这个适合的单位

由dip和具体像素值的对应公式dip值 =设备密度/160* pixel值

Android设备屏幕大小及密度的系统参数

/**

* 系统参数类

*

* @author wader

*

*/

public class MySystemParams {

private final String TAG = "SystemParams";

private static MySystemParams params;

public int screenWidth;// 屏幕宽度,单位为px

public int screenHeight;// 屏幕高度,单位为px

public int densityDpi;// 屏幕密度,单位为dpi

public float scale;// 缩放系数,值为 densityDpi/160

public float fontScale;// 文字缩放系数,同scale

public final static int SCREEN_ORIENTATION_VERTICAL = 1; // 屏幕状态:横屏

public final static int SCREEN_ORIENTATION_HORIZONTAL = 2; // 屏幕状态:竖屏

public int screenOrientation = SCREEN_ORIENTATION_VERTICAL;// 当前屏幕状态,默认为竖屏

/**

* 私有构造方法

*

* @param activity

*/

private MySystemParams(Activity activity) {

DisplayMetrics dm = new DisplayMetrics();

activity.getWindowManager().getDefaultDisplay().getMetrics(dm);

screenWidth = dm.widthPixels;

screenHeight = dm.heightPixels;

densityDpi = dm.densityDpi;

scale = dm.density;

fontScale = dm.scaledDensity;

screenOrientation = screenHeight > screenWidth ? SCREEN_ORIENTATION_VERTICAL

: SCREEN_ORIENTATION_HORIZONTAL;

}

}

--------------------------------------------------------------------------------

/**

* 将px值转换为dp值

*/

public static int px2dp(Context context, float pxValue) {

final float scale = context.getResources().getDisplayMetrics().density;

return (int) (pxValue / scale + 0.5f);

}

/**

* 将dp值转换为px值

*/

public static int dp2px(Context context, float dpValue) {

final float scale = context.getResources().getDisplayMetrics().density;

return (int) (dpValue * scale + 0.5f);

}

/**

* 将px值转换为sp值

*/

public static int px2sp(Context context, float pxValue) {

final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;

return (int) (pxValue / fontScale + 0.5f);

}

/**

* 将sp值转换为px值

*/

public static int sp2px(Context context, float spValue) {

final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;

return (int) (spValue * fontScale + 0.5f);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值