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层直接加载图片更便捷。

时间: 2025-01-21 13:45:04

android开发图片分辨率问题解决方案的相关文章

Android大图片裁剪终极解决方案(上:原理分析)

http://blog.csdn.net/floodingfire/article/details/8144604 约几个月前,我正为公司的APP在Android手机上实现拍照截图而烦恼不已.     上网搜索,确实有不少的例子,大多都是抄来抄去,而且水平多半处于demo的样子,可以用来讲解知识点,但是一碰到实际项目,就漏洞百出.     当时我用大众化的解决方案,暂时性的做了一个拍照截图的功能,似乎看起来很不错.问题随之而来,我用的是小米手机,在别的手机上都运行正常,小米这里却总是碰钉子.虽然

Android 开发图片压缩/缩略图的方法

在开发图片浏览器等软件是,很多时候要显示图片的缩略图,而一般情况下,我们要将图片按照固定大小取缩略图,一般取缩略图的方法是使用BitmapFactory的decodeFile方法,然后通过传递进去 BitmapFactory.Option类型的参数进行取缩略图,在Option中,属性值inSampleSize表示缩略图大小为原始图片大小的几分之一,即如果这个值为2,则取出的缩略图的宽和高都是原始图片的1/2,图片大小就为原始大小的1/4. 然而,如果我们想取固定大小的缩略图就比较困难了,比如,我

Android大图片裁剪终极解决方案

http://my.oschina.net/ryanhoo/blog/86865     上一篇博客中,我们学习到了如何使用Android相册截图.在这篇博客中,我将向大家展示如何拍照截图.     拍照截图有点儿特殊,要知道,现在的Android智能手机的摄像头都是几百万的像素,拍出来的图片都是非常大的.因此,我们不能像对待相册截图一样使用Bitmap小图,无论大图小图都统一使用Uri进行操作.     一.首先准备好需要使用到的Uri: 1 private static finalStrin

Android大图片裁剪终极解决方案(中:从相册截图)

http://blog.csdn.net/floodingfire/article/details/8144615

Android大图片裁剪终极解决方案(下:拍照截图)

http://blog.csdn.net/floodingfire/article/details/8144617

android开发-Android开发入门初学遇到的问题

问题描述 Android开发入门初学遇到的问题 Android开发入门学习,使用的是<第一行代码Android>郭霖著在学习至2.2.5 在活动中使用Toast中产生如下疑问,期待各位前辈帮我解答图中为输入的代码 问题1.书中原话是可以通过findViewById()方法获取到在布局文件中定义的元素,这里我们传入R.id.button 1,来得到按钮的实例,这里的按钮的实例是什么意思能否麻烦详细解释一下. 问题2.书中说findViewById()返回的是一个View对象,我们需要向下转型将它

android 音乐播放器-android开发音乐播放器

问题描述 android开发音乐播放器 android开发音乐播放器怎么把歌曲放到项目中,一起打包到apk中??? 解决方案 一般多媒体文件都是放在raw目录下的,但音乐播放器的话,不建议把歌曲打包到apk中,可以把歌曲放在SD卡中,通过扫描sd卡的方式获取歌曲 解决方案二: 音乐播放器中综合了以下内容: SeekBar.ListView.广播接收者(以代码的形式注册Receiver).系统服务.MediaPlayer 实现的功能: 1.暂停/播放.下一首/上一首,点击某一首时播放 2.支持拖动

android开发出现问题了

问题描述 android开发出现问题了 解决方案 解决方案二: 在res/values/strings.xml文件中加入action_setting的值就可以了 你没设置 所以找不到

Android开发中如何解决加载大图片时内存溢出的问题

Android开发中如何解决加载大图片时内存溢出的问题    在Android开发过程中,我们经常会遇到加载的图片过大导致内存溢出的问题,其实类似这样的问题已经屡见不鲜了,下面将一些好的解决方案分享给大家.   尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存. 因此,改用先通过Bitmap