• android开发图片分辨率问题解决方案


    android开发图片分辨率问题解决方案

      

    一直受到android开发图片分辨率问题困扰.drawable-(xdpi,hdpi,mdpi,ldpi,nodpi)这几个文件夹到底怎么放图片呢?

     

    dpi是什么呢?

    dpi是“dot per inch”的缩写,每英寸像素数。
    四种密度分类: ldpi (low), mdpi (medium), hdpi (high), and xhdpi (extra high)
    一般情况下的普通屏幕:ldpi是120,mdpi是160,hdpi是240,xhdpi是320。

    dpi计算公式
    DPI=对角线的像素值/尺寸

    手机屏幕分辨率和屏幕密度是两码事!并不是800*480的分辨率手机图片就应该放在hdpi文件夹中。5.0英寸 800*480属于mdpi

    也可以通过代码获取:

    1. DisplayMetrics metric = new DisplayMetrics(); 
    2.        getWindowManager().getDefaultDisplay().getMetrics(metric); 
    3.        int width = metric.widthPixels;  // 屏幕宽度(像素) 
    4.        int height = metric.heightPixels;  // 屏幕高度(像素) 
    5.        float density = metric.density;  // 屏幕密度(0.75 / 1.0 / 1.5) 
    6.        int densityDpi = metric.densityDpi;  // 屏幕密度DPI(120 / 160 / 240) 

    android会根据屏幕本身的尺寸与密度特性,自动载入对应的资源,并把它们从逻辑像素(DIP,用于定义界面布局)转换成屏幕上的物理像素。

    首先看看 系统是如何通过Resources的getDrawable(int id)方法找图片的

    1. public Drawable getDrawable(int id) throws NotFoundException { 
    2.         TypedValue value; 
    3.         synchronized (mAccessLock) { 
    4.             value = mTmpValue; 
    5.             if (value == null) { 
    6.                 value = new TypedValue(); 
    7.             } else { 
    8.                 mTmpValue = null
    9.             } 
    10.             getValue(id, value, true); 
    11.         } 
    12.         Drawable res = loadDrawable(value, id); 
    13.         synchronized (mAccessLock) { 
    14.             if (mTmpValue == null) { 
    15.                 mTmpValue = value; 
    16.             } 
    17.         } 
    18.         return res; 
    19.     } 
    20.   

    TypedValue 我们可以理解为存储数据的类型,主要被Resouces使用于持有的资源值
    通过getValue(id,value,true)方法去得到该id的资源的属性

    1. public void getValue(int id, TypedValue outValue, boolean resolveRefs) 
    2.             throws NotFoundException { 
    3.         boolean found = mAssets.getResourceValue(id, 0, outValue, resolveRefs); 
    4.         if (found) { 
    5.             return
    6.         } 
    7.         throw new NotFoundException("Resource ID #0x" 
    8.                                     + Integer.toHexString(id)); 
    9.     } 
    10.   

    最后通过loadDrawable(value, id)得到drawable,该方法到了底层的C代码,大致意思就是通过TypedValue中的方法和属性就可以获得我们想要的属性值,然后加载图片

    OK,下面来做个实验.

    试验一: 手机是1280*720 4.3英寸 属于xdpi 图片分辨率为960*640 (按正常图片不缩放 图片放在手机里面 应该不会充满 整个手机) 我把图片放在不

    文件夹 加载时间(ms) 图片显示 说明

    drawable 311 充满屏幕 图片有拉伸

    drawable-nodpi 130 未充满屏幕 图片显示正常

    drawable-ldpi 442 充满屏幕 图片有拉伸

    drawable-mdpi 383 充满屏幕 图片有拉伸

    drawable-hdpi 226 充满屏幕 图片有拉伸

    drawable-xhdpi 109 未充满屏幕 图片显示正常

    试验二: 手机是800*480 4.3英寸 属于hdpi 图片分辨率为960*640 (按正常图片不缩放 图片放在手机里面 应该充满 整个手机) 我把图片放在不同drawable文件夹中

    文件夹 加载时间(ms) 图片显示 说明

    drawable 290 充满屏幕 图片拉伸

    drawable-nodpi 127 充满屏幕 图片显示正常

    drawable-ldpi 369 充满屏幕 图片拉伸

    drawable-mdpi 346 充满屏幕 图片拉伸

    drawable-hdpi 124 充满屏幕 图片显示正常

    drawable-xhdpi 241 未充满屏幕 图片缩放

    得到结论:

    drawable-nodpi 中 图片不会被拉伸

    系统在得到图片时候,会先到设备对应的dpi的文件夹下去去找资源文件,找到后应该不会做缩放直接返回图片。

    如果没有在对应的dpi文件夹中找到,回去其他文件夹中查找,找到后会做相应的缩放。

    在高dpi找到的图片会缩放,在低dpi的会拉伸

    还有就是 源码中可以看出 loadDrawable的过程实在C层做的。通过系统资源id加载会比java层直接加载图片更便捷。

  • 相关阅读:
    C语言编译包含math库加参数-lm
    C语言浮点类型有效位(float, double,long double)
    C语言速记(宏)
    C语言速记6(结构体)
    asp.net Core依赖注入汇总
    跨域请求(转载)
    UnobtrusiveJavaScriptEnabled、ClientValidationEnabled(转载)
    到值类型“System.DateTime”的强制转换失败,因为具体化值为 null。结果类型的泛型参数或查询必须使用可以为 null 的类型。
    软件开发PPT中造图片软件:ProcessOn
    EF接收数据通用实体模型
  • 原文地址:https://www.cnblogs.com/new0801/p/6175843.html
Copyright © 2020-2023  润新知