62.Android之各分辨率定义的图片规格

转载:http://www.nljb.net/default/Android%E4%B9%8B%E5%90%84%E5%88%86%E8%BE%A8%E7%8E%87%E5%AE%9A%E4%B9%89%E7%9A%84%E5%9B%BE%E7%89%87%E8%A7%84%E6%A0%BC/

各种规格总结


  1. // 首先阐释一些术语和概念
  2. 屏幕尺寸(screen size): 屏幕的对角线测量。
  3. 为了方便,Android把所有的屏幕尺寸分为了4个广义的大小:小、正常、大、更大
  4. 屏幕密度(screen density): 屏幕占据的物理区域所含像素的个数
  5. 通常被称为dpi(dots per inch)即每英寸的像素点数
  6. 分辨率(resolution): 屏幕上物理像素的点数
  7. 例如,有一个240px*400px的屏幕,可以理解为在这个屏幕上横着有400条线,每条线上有240个像素点
  8. 像素(px): 屏幕上的点
  9. dip(dp):Density-independent pixel--->与密度无关的像素(下面将详细讲解)


由于JPG容易失真, 在Android开发中尽量避免使用.jpg图片, 应该使用.png图片, 它采用了从LZ77派生的无损数据压缩算法.


补充

  1. 屏幕:尺寸5.1,分辨率1920X1080
  2. DPI:1920^2+1080^2(v)/5.1=2202/5.1=431
  3. mdpi 120dpi ~ 160dpi
  4. hdpi 160dpi ~ 240dpi
  5. xhdpi 240dpi ~ 320dpi
  6. xxhdpi 320dpi ~ 480dpi
  7. xxxhdpi 480dpi ~ 640dpi
  8. 在设计图标时:
  9. 对于五种主流像素密度(MDIP, HDPI, XHDPI, XXHDPI, XXXHDPI)
  10. 应按照(2:3:4:6:8)的比例进行缩放,(1x, 1.5x, 2x, 3x, 4x)
  11. 例如:
  12. 尺寸为48x48dp的图标,表示在MDPI的屏幕上其尺寸应为48x48px
  13. 在HDPI的屏幕上其实际大小是MDPI的1.5倍(72x72px)… 依此类推
  14. 字体:
  15. 对于字体的使用,官方不建议使用低于12号字体大小值
  16. 图片内存占用:
  17. drawable-xxhdpi 11.65M
  18. drawable 74.97M
  19. drawable-mhdpi 74.95M
  20. drawable-hdpi 35.38M
  21. 在图片密度不匹配的情况下,低分辨率图片会被拉伸到高分辨率图片

密度陷阱

  1. 虽然说dp可以去除不同像素密度的问题,使得1dp在不同像素密度上面的显示效果相同,但是还是由于Android屏幕设备的多样性
  2. 如果使用dp来作为度量单位,并不是所有的屏幕的宽度都是相同的dp长度
  3. 比如说:
  4. Nexus S和Nexus One 属于hdpi 屏幕宽度是320dp
  5. Nexus 5 属于xxhdpi 屏幕宽度是360dp
  6. Galaxy Nexus 属于xhdpi 屏幕宽度是384dp
  7. Nexus 6 属于xxxhdpi 屏幕宽度是410dp
  8. 所以说,光Google自己一家的产品就已经有这么多的标准,而且屏幕宽度和像素密度没有任何关联关系
  9. 即使我们使用dp,在320dp宽度的设备和410dp的设备上,还是会有90dp的差别。
  10. 当然,我们尽量使用match_parent和wrap_content,尽可能少的用dp来指定控件的具体长宽
  11. 再结合上权重,大部分的情况我们都是可以做到适配的。
  1. 此外还有一个解决办法,也就是指定所有分辨率密度对应关系
  2. // 下面是生成的一个320*480分辨率的文件
  3. // 因为宽高分割之后总分数和像素数相同
  4. // 所以x1就是1px,以此类推
  5. <?xml version="1.0" encoding="utf-8"?>
  6. <resources><dimen name="x1">1.0px</dimen>
  7. <dimen name="x2">2.0px</dimen>
  8. <dimen name="x3">3.0px</dimen>
  9. <dimen name="x4">4.0px</dimen>
  10. <dimen name="x5">5.0px</dimen>
  11. <dimen name="x6">6.0px</dimen>
  12. <dimen name="x7">7.0px</dimen>
  13. <dimen name="x8">8.0px</dimen>
  14. <dimen name="x9">9.0px</dimen>
  15. <dimen name="x10">10.0px</dimen>
  16. ...省略好多行
  17. <dimen name="x300">300.0px</dimen>
  18. <dimen name="x301">301.0px</dimen>
  19. <dimen name="x302">302.0px</dimen>
  20. <dimen name="x303">303.0px</dimen>
  21. <dimen name="x304">304.0px</dimen>
  22. <dimen name="x305">305.0px</dimen>
  23. <dimen name="x306">306.0px</dimen>
  24. <dimen name="x307">307.0px</dimen>
  25. <dimen name="x308">308.0px</dimen>
  26. <dimen name="x309">309.0px</dimen>
  27. <dimen name="x310">310.0px</dimen>
  28. <dimen name="x311">311.0px</dimen>
  29. <dimen name="x312">312.0px</dimen>
  30. <dimen name="x313">313.0px</dimen>
  31. <dimen name="x314">314.0px</dimen>
  32. <dimen name="x315">315.0px</dimen>
  33. <dimen name="x316">316.0px</dimen>
  34. <dimen name="x317">317.0px</dimen>
  35. <dimen name="x318">318.0px</dimen>
  36. <dimen name="x319">319.0px</dimen>
  37. <dimen name="x320">320px</dimen>
  38. </resources>
  39. // 那么1080*1960分辨率下是什么样子呢?
  40. // 我们可以看下,由于1080和320是3.37倍的关系
  41. // 所以x1=3.37px
  42. <?xml version="1.0" encoding="utf-8"?>
  43. <resources><dimen name="x1">3.37px</dimen>
  44. <dimen name="x2">6.75px</dimen>
  45. <dimen name="x3">10.12px</dimen>
  46. <dimen name="x4">13.5px</dimen>
  47. <dimen name="x5">16.87px</dimen>
  48. <dimen name="x6">20.25px</dimen>
  49. <dimen name="x7">23.62px</dimen>
  50. <dimen name="x8">27.0px</dimen>
  51. <dimen name="x9">30.37px</dimen>
  52. <dimen name="x10">33.75px</dimen>
  53. ...省略好多行
  54. <dimen name="x300">1012.5px</dimen>
  55. <dimen name="x301">1015.87px</dimen>
  56. <dimen name="x302">1019.25px</dimen>
  57. <dimen name="x303">1022.62px</dimen>
  58. <dimen name="x304">1026.0px</dimen>
  59. <dimen name="x305">1029.37px</dimen>
  60. <dimen name="x306">1032.75px</dimen>
  61. <dimen name="x307">1036.12px</dimen>
  62. <dimen name="x308">1039.5px</dimen>
  63. <dimen name="x309">1042.87px</dimen>
  64. <dimen name="x310">1046.25px</dimen>
  65. <dimen name="x311">1049.62px</dimen>
  66. <dimen name="x312">1053.0px</dimen>
  67. <dimen name="x313">1056.37px</dimen>
  68. <dimen name="x314">1059.75px</dimen>
  69. <dimen name="x315">1063.12px</dimen>
  70. <dimen name="x316">1066.5px</dimen>
  71. <dimen name="x317">1069.87px</dimen>
  72. <dimen name="x318">1073.25px</dimen>
  73. <dimen name="x319">1076.62px</dimen>
  74. <dimen name="x320">1080px</dimen>
  75. </resources>
  1. import java.io.File;
  2. import java.io.FileNotFoundException;
  3. import java.io.FileOutputStream;
  4. import java.io.PrintWriter;
  5. public class MakeXml {
  6. private final static String rootPath =
  7. "C:\\Users\\Administrator\\Desktop\\layoutroot\\values-{0}x{1}\\";
  8. private final static float dw = 320f;
  9. private final static float dh = 480f;
  10. private final static String WTemplate = "<dimen name=\"x{0}\">{1}px</dimen>\n";
  11. private final static String HTemplate = "<dimen name=\"y{0}\">{1}px</dimen>\n";
  12. public static void main(String[] args) {
  13. makeString(320, 480);
  14. makeString(480,800);
  15. makeString(480, 854);
  16. makeString(540, 960);
  17. makeString(600, 1024);
  18. makeString(720, 1184);
  19. makeString(720, 1196);
  20. makeString(720, 1280);
  21. makeString(768, 1024);
  22. makeString(800, 1280);
  23. makeString(1080, 1812);
  24. makeString(1080, 1920);
  25. makeString(1440, 2560);
  26. }
  27. public static void makeString(int w, int h) {
  28. StringBuffer sb = new StringBuffer();
  29. sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
  30. sb.append("<resources>");
  31. float cellw = w / dw;
  32. for (int i = 1; i < 320; i++) {
  33. sb.append(WTemplate.replace("{0}", i + "").replace("{1}",
  34. change(cellw * i) + ""));
  35. }
  36. sb.append(WTemplate.replace("{0}", "320").replace("{1}", w + ""));
  37. sb.append("</resources>");
  38. StringBuffer sb2 = new StringBuffer();
  39. sb2.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
  40. sb2.append("<resources>");
  41. float cellh = h / dh;
  42. for (int i = 1; i < 480; i++) {
  43. sb2.append(HTemplate.replace("{0}", i + "").replace("{1}",
  44. change(cellh * i) + ""));
  45. }
  46. sb2.append(HTemplate.replace("{0}", "480").replace("{1}", h + ""));
  47. sb2.append("</resources>");
  48. String path = rootPath.replace("{0}", h + "").replace("{1}", w + "");
  49. File rootFile = new File(path);
  50. if (!rootFile.exists()) {
  51. rootFile.mkdirs();
  52. }
  53. File layxFile = new File(path + "lay_x.xml");
  54. File layyFile = new File(path + "lay_y.xml");
  55. try {
  56. PrintWriter pw = new PrintWriter(new FileOutputStream(layxFile));
  57. pw.print(sb.toString());
  58. pw.close();
  59. pw = new PrintWriter(new FileOutputStream(layyFile));
  60. pw.print(sb2.toString());
  61. pw.close();
  62. } catch (FileNotFoundException e) {
  63. e.printStackTrace();
  64. }
  65. }
  66. public static float change(float a) {
  67. int temp = (int) (a * 100);
  68. return temp / 100f;
  69. }
  70. }


应用程序图标 (Icon)应当是一个 Alpha 通道透明的32位 PNG 图片。

  1. 由于安卓设备众多,一个应用程序图标需要设计几种不同大小,如:
  2. LDPI (Low Density Screen,120 DPI),其图标大小为 36 x 36 px。
  3. MDPI (Medium Density Screen, 160 DPI),其图标大小为 48 x 48 px。
  4. HDPI (High Density Screen, 240 DPI),其图标大小为 72 x 72 px。
  5. xhdpi (Extra-high density screen, 320 DPI),其图标大小为 96 x 96 px。
  6. 建议在设计过程中,在四周空出几个像素点使得设计的图标与其他图标在视觉上一致,例如,
  7. 96 x 96 px 图标可以画图区域大小可以设为 88 x 88 px, 四周留出4个像素用于填充(无底色)。
  8. 72 x 72 px 图标可以画图区域大小可以设为 68 x 68 px, 四周留出2个像素用于填充(无底色)。
  9. 48 x 48 px 图标可以画图区域大小可以设为 46 x 46 px, 四周留出1个像素用于填充(无底色)。
  10. 36 x 36 px 图标可以画图区域大小可以设为 34 x 34 px, 四周留出1个像素用于填充(无底色)。

  1. 每英寸像素数, 可以反映屏幕的清晰度,用于缩放UI的
  2. ldpi (low) ~120dpi
  3. mdpi (medium) ~160dpi
  4. hdpi (high) ~240dpi
  5. xhdpi (extra-high) ~320dpi
  6. xxhdpi (extra-extra-high) ~480dpi
  7. xxxhdpi (extra-extra-extra-high) ~640dpi
  1. drawable-ldpi 放低分辨率的图片,即QVGA(240×320)
  2. drawable-mdpi 放中分辨率的图片,即HVGA(320×480)
  3. drawable-hdpi 放高分辨率的图片,如WVGA(480x800),FWVGA (480x854)。
  4. drawable-xhdpi 放高分辨率的图片,即720p(1280×720)
  5. drawable-xxhdpi 放高分辨率的图片,即1080p(1920×1080)


Android设备屏幕尺寸分布

  1. 上图可以看出
  2. 对应normal尺寸的屏幕范围集中在常见的3到5寸屏之间
  3. large尺寸对应的就主要是5到7寸的nottpad之类的设备,例如三星的Note和Nexus7平板等
  4. 接下来是屏幕密度(dpi),需要说明的是,平时所说的屏幕分辨率其实不能作为屏幕适配的依据
  5. 应该依据屏幕密度和屏幕尺寸来换算,屏幕密度是指每英寸屏幕内容纳的像素数
  6. 屏幕密度从ldpi到xhdpi分别对应为120dpi、160dpi、240dpi、320dpi
  7. 屏幕密度越高、分辨率越高、屏幕尺寸越小就产生了视网膜屏幕。


DIP单位详解

  1. Android规定一个dip的大小相当于160dpi屏幕上的一个像素
  2. 它是系统为“中等的”密度屏设定的基准密度,在不同dpi屏幕上dp对应的像素数是不同的
  3. 需要时,基于当前屏的实际密度,系统会透明地放缩dip单。
  4. dip单位根据公式像素值 = [dip*(dpi/160)](px)(其中px是单位)转化为屏幕像素。
  5. 根据此公式可以计算出一个dip分别在120dpi、160dpi、240dpi、320dpi
  6. 屏幕中对应的像素数分别为0.75、1、1.5、2.0,比例为3:4:6:8。
  7. 因此,在不同屏幕密度上,以mdpi作为基准,对位图进行3:4:6:8比例的放缩会达到适配的效果。
  1. dip与一般的px不太一样,它是独立于屏幕密度的。什么是独立于密度?
  2. 先来说下一般的px,如果将一个相同长宽像素的图片放在不同屏幕密度大小的屏幕中
  3. 那么,在低密度屏幕中图片会显示的很大,在高密度屏幕中则会显示的很小;
  4. 但是,如果使用dip为单位的图片显示的效果则是,屏幕密度越大的手机,图片显示的像素也相应增大
  5. 这样在屏幕密度大的手机和屏幕密度小的手机上,图片看上去大小基本相同。
  6. 有了上文对dip的讲解,是否对这个现象有所理解呢?

举个例子来说一下:

  1. 现在有三个物理长宽分别为3寸、4寸,屏幕密度分别为120dpi、160dpi、240dpi的手机
  2. 则三个屏幕的分辨率分别为360px*480px、480px*640px、

  1. 将三个手机屏幕的宽分为三等份,则根据dpi的定义,三个屏幕中每等份分别容纳120px、160px、240px。
  2. 现在假设有一个控件imageview 它的长宽分别为160px、160px,还有一个160px*160px的图片资源
  3. 当程序运行时,该图片在三个屏幕上会呈现以下效果:

  1. 如果将imageview的长宽分别改为160dip、160dip,图片将在三个屏幕上呈现以下效果:

  1. 上文提到在这三种屏幕密度下一个dip分别对应0.75px、1px、1.5px
  2. 所以在三种屏幕上该图片占据120px、160px、240px,各自占屏幕的三分之一,所以看起来是一样大的。
  1. 由上文可总结出Android在适配不同屏幕密度时,可以用dip作为控件的单位,视情况放缩dip单位。
  2. 当应用没有指出图片对应的控件的大小,Android是如何让图片适配不同屏幕的呢?
  1. 在Android2.1之前,开发应用时只有一个放图片资源的drawable文件夹,这样程序在不同屏幕密度的手机上运行时
  2. 系统只会从drawable这个文件夹下调图片资源,并且系统会默认认为这个文件夹下的所有资源是为mdpi屏幕提供的
  3. 所以在hdpi屏幕上系统会按比例将drawable下的图片扩大为原来的1.5倍
  4. 在ldpi屏幕上系统会按比例将drawable下的图片缩小为原来的0.75倍
  5. 这样会大大降低页面效果。
  6. 在Android2.1以及之后,出现了drawable-ldpi、drawable-mdpi、drawable-hdpi、drawable-xhdpi、drawable-xxhdpi。
  7. 在这些文件下提供的图片大小最好是3:4:6:8:12。
  8. 程序在不同的屏幕密度下运行时,会首先去符合当前屏幕密度的文件夹下找对应的资源
  9. 如果没有,系统会以最省力为前提去别的文件夹下找对应的资源并对其进行相应的缩放
  10. 如果还没有,就回去默认的drawable文件夹下找,然后按照2.1之前的规则缩放
  11. 如果还没有找到,应用就会报错或者直接crash掉了。

举个例子

  1. 现在有一个ldpi的手机屏幕,有一个应用在其上运行(假如只有ldpi、mdpi、hdpi还有drawable四个存放图片的文件夹)
  2. 并需要调用一个图片a.png(在下文中用a来代替a.png)。Android系统会经历以下流程:

  1. 将hdpi中的图片大小缩小为原来的一半相比将mdpi中的图片大小缩小为原来的3/4,计算机要省力,只需进行简单地右移一位操作。
  2. 所以系统在ldpi下找不到a的时候会首先去hdpi下去找。当存在xhdpi、xxhdpi时,系统会按相同的规则去调用资源。
  3. Drawable-ldpi 3、Drawable-mdpi 4、Drawable-hdpi 6中的3、4、6指的是同一个图片在三个文件夹下的大小之比。
  1. Android开发者在做图片适配时需要注意一下两点
  2. 盛放图片的控件要用dip单位来定义其长宽。
  3. 最好在ldpi、mdpi、hdpi、xhdpi、xxhdpi文件夹下提供大小比例为3:4:6:8:12的图片。
  4. 当然如果有质量好的.9.png图片的话,提供一个也可以。






笔记

  1. Google 提供的 PX 转 DP 的公式 ( px * 160 ) / PPI 获取 DP 值
  2. 通过测试,Android 系统是使用默认 DP 来作为基数,而不是使用实际手机中的 DPI ,只是取相近的像素值
  3. 比如 5寸手机 1920X1080 分辨率 DP 为 440 ,但是 Android 手机使用是 480 的 DP
  4. 1920X1080 为基数 3倍数 而 1280X720 为基数 2倍数
  5. 所以现在遇到两个问题,一个设计给的PX我转换成DP则使用
  6. PX * 160 / 480 后的值作为 像素间距大小 等值
  7. 另外一个就是发现非XML文件中设置DP即使进行了转换也与设计效果相差很多
  8. 所以在这种情况下使用 百分比进行计算
  9. 读取手机真是分辨率 宽 / 百分比 和 高 / 百分比
  1. dip : device independent pixels 设备无关像素(dp就是dip)
  2. dpi :dots per inch ,密度(一英寸多少个点)
时间: 2024-10-06 16:41:53

62.Android之各分辨率定义的图片规格的相关文章

自动生成Android不同分辨率下的图片

Android屏幕分辨率适配的图标处理比较麻烦,让UI做不同尺寸的图片也挺浪费时间的,并且容易出错,于是用Python写了个工具自动化处理图片,UI只需要做好1080*1920分辨率下的图片就可以了,其它分辨率的图片自动生成. import os.path import sys from PIL import Image """ 自动生成不同分辨率下的App图片 UI设计1080*1920分辨率图片,放在drawable-xxhdpi目录下,自动生成其它的分辨率图片 &quo

图片--Android有效解决加载大图片时内存溢出的问题

Android有效解决加载大图片时内存溢出的问题 博客分类: Android Android游戏虚拟机算法JNI 尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,因为这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存. 因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView

Android设计中的.9.png图片

.9.png是一种能够自己定义拉伸特定区域的图片格式. 简书:Android设计中的.9.png图片 在Android的UI设计开发中,非常多控件须要适配不同的手机分辨率进行拉伸或者压缩,这样就出现了能够随意调整大小的一种图片格式".9.png".这样的图片是用于Android开发的一种特殊的图片格式,它能够指定特定的区域进行拉伸而不失真.同一时候能够指定前景内容的显示区域.即.9.png图片的用处能够概括为以下两点: - .9.png图片在图片拉伸的时候特定的区域不会发生图片失真.

Android之ListView异步加载图片且仅显示可见子项中的图片

折腾了好多天,遇到 N 多让人崩溃无语的问题,不过今天终于有些收获了,这是实验的第一版,有些混乱,下一步进行改造细分,先把代码记录在这儿吧. 网上查了很多资料,发现都千篇一律,抄来抄去,很多细节和完整实例都没看到,只有自己一点点研究了,总体感觉 android 下面要显示个图片真不容易啊. 项目主要实现的功能: 异步加载图片图片内存缓存.异步磁盘文件缓存解决使用 viewHolder 后出现的图片错位问题优化列表滚动性能,仅显示可见子项中的图片无需固定图片显示高度,对高度进行缓存使列表滚动时不会

android之使用GridView+仿微信图片上传功能(附源代码)

由于工作要求最近在使用GridView完成图片的批量上传功能,我的例子当中包含仿微信图片上传.拍照.本地选择.相片裁剪等功能,如果有需要的朋友可以看一下,希望我的实际经验能对您有所帮助. 直接上图,下面的图片就是点击"加号"后弹出的对话框,通过对话框可以根据自己需求进行相片选择. 项目结构: 下面直接上代码. 整体的布局文件activity_main.xml 1 <LinearLayout xmlns:android="http://schemas.android.co

Android自适应屏幕分辨率与国际化

一.当横屏切换成竖屏时,解决的办法: 在res目录下建立layout-port和layout-land两个目录,里面分别放置竖屏和横屏两种布局文件,当手机屏幕方向变化的时android系统会自动调用相应的布局文件. 当然还有办法就是不切换.要么都是横屏或者要么都是竖屏.可以在AndroidManifest.xml文件中设置, 比如某个Activity设置为android:screenOrientation="portrait" 这样就一直保持竖屏, 如果设置为 android:scre

Android 从 Android 本地图库选择多个图片

原文地址 本文说明如何从 Android 本地图库选择多个图片.作者考虑很多解决方案. 演示从 Android 本地图库选择多个图片,有两个方法可以实现从图库中选择多个图片: 用 Intent 获取多个图片 自定义图库从本地获取和加载图片 下载 Demo 下载 Demo 后将 QDReader 图片目录复制到 sd 卡上 环境 Windows 2008 R2 64 位 Eclipse ADT V22.6.2,Android 4.4.2(API 19) SAMSUNG GT-8618,Androi

【Android进阶】使用HttpURLConnection实现图片的下载与现显示

虽然我们在开发中经常使用别人已经开发好的开源框架,但是,了解这些框架底层的实现,能够让我们更好的理解功能的实现. 这篇文章主要介绍使用HttpURLConnection对象,实现图片文件的下载,以及显示. 我们的思路是,首先使用HttpURLConnection实现图片文件的下载,在下载结束之后,使用handler异步的显示图片. 因为功能比较简单,我只把代码贴在下面,注释很详细 /** * 使用HttpURLConnection实现图片的下载与现显示 * * @author ZhaoKaiQi

Android 自定义 HorizontalScrollView 打造再多图片(控件)也不怕 OOM 的横向滑动效果

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38140505 自从Gallery被谷歌废弃以后,Google推荐使用ViewPager和HorizontalScrollView来实现Gallery的效果.的确HorizontalScrollView可以实现Gallery的效果,但是HorizontalScrollView存在一个很大的问题,如果你仅是用来展示少量的图片,应该是没问题的,但是如果我希望HorizontalScr