android怎么读取图片_android摸仪器 读取远程图片,获取图片远程地址 - CSDN
精华内容
参与话题
  • 1、程序,把Assets中的图像显示出来 try {  BufferedInputStream bis = new BufferedInputStream(getAssets()  .open("a.bmp"));  Bitmap bm = BitmapFactory.decodeStream(bis);  imageView01....

    1、程序,把Assets中的图像显示出来

    try {
        BufferedInputStream bis = new BufferedInputStream(getAssets()
          .open("a.bmp"));
        Bitmap bm = BitmapFactory.decodeStream(bis);
        imageView01.setImageBitmap(bm);
       } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        System.out.println("==========file not found======");
       }
    2、原理:Android中的资源分析
    资源是Android应用程序中重要的组成部分。在应用程序中经常会使用字符串、菜单、图像、声音、视频等内容,都可以称之为资源。通过将资源放到与apk文件中与Android应用程序一同发布,在资源文件比较大的情况下,可以通过将资源作为外部文件来使用,我们将分析如何在Android应用程序中存储这些资源。
    一、资源的存储
    在android中,资源大多都是保存在res目录中,例如布局资源以XML文件的形式保存在res\layout目录中;图像资源保存着res\drawable目录中;菜单资源保存在res\menu目录中。ADT在生成apk文件时,这些目录中的资源都会被编译,然后保存到apk文件中。如果将资源文件放到res\raw目录中,资源将在不编译的情况下放入apk文件中。在程序运行时可以使用InputStream来读取res\raw目录中的资源。
    如果使用的资源文件过大,我们可以考虑将资源文件作为外部文件单独发布。Android应用程序会从手机内存或者SD卡读取这些资源文件。
    二、资源的种类
    从资源文件的类型来划分,我们可以将资源文件划分为XML、图像和其它。以XML文件形式存储的资源可以放在res目录中的不同子目录里,用来表示不同种类的资源;而图像资源会放在res\drawable目录中。除此之外,可以将任意的资源嵌入Androidy应用程序中。比如音频和视频等,一般这些资源放在res\raw目录中。
    表1、 Android支持的资源
    目录 资源类型 描述
    Res\values 
    XML
    保存字符串、颜色、尺寸、类型、主题等资源,可以是任意文件名。对于字符串、颜色、尺寸等信息采用
    Key-value形式表示,对于类型、主题等资源,采用其它形式表示
    Res\layout 
    XML
    保存布局信息。一个资源文件表示一个View或ViewGroup的布局
    Res\menu 
    XML
    保存菜单资源。一个资源文件表示一个菜单(包括子菜单)
    Res\anim 
    XML
    保存与动画相关的信息。可以定义帧(frame)动画和补间(tween)动画
    Res\xml 
    XML
    在该目录的文件可以是任意类型的XML文件,这些XML文件可以在运行时被读取。
    Res\raw 
    任意类型
    在该目录中的文件虽然也会被封装在apk文件中,但不会被编译。在该目录中可以放置任意类型的文件,例如,各种类型的文档、音频、视频文件等
    Res\drawable 
    图像
    该目录中的文件可以是多种格式的图像文件,例如,bmp、png、gif、jpg等。在该目录中的图像不需要分辨率非常高,aapt工具会优化这个目录中的图像文件。如果想按字流读取该目录下的图像文件,需要将图像文件放在res\raw目录中。
    assets 
    任意类型
    该目录中的资源与res\raw中的资源一样,也不会被编译。但不同的是该目录中的资源文件都不会生出资源ID
    三、资源文件的命名
    每一个资源文件或资源文件中的key-value对都会在ADT自动生成的R类(在R.java文件中)中找到相对应的ID.其中资源文件名或key-value对中的key就是R类中的java变量名。因此,资源文件名好key的命名首先要符合java变量的命名规则。
    除了资源文件和key本身的命名要遵循相应的规则外,多个资源文件和key也要遵循唯一的原则。也就是说,同类资源的文件名或key不能重复。例如,两个表示字符串资源的key不能重复,就算这两个key在不同的XML文件中也不行。
    由于ADT在生成ID时并不考虑资源文件的扩展名,因此,在res\drawable、res\raw等目录中不能存在文件名相同,扩展名不同的资源文件。例如在res\drawable目录不能同时放置icon.jpg和icon.png文件。
    四、资源使用示例
    在Android SDK中不仅提供了大量的系统资源,而且还允许开发人员定制自己的资源。不管是系统资源,还是自定义的资源,一般都会将这些资源放在res目录中,然后通过R类中的相应ID来引用这些资源。接下来将针对于XML类资源的使用进行分析。
    XML资源实际上就是XML格式的文本文件,这些文件必须放在res\xml目录中。可以通过Resources.getXml方法获得处理指定XML文件的XmlResourceParser对象。实际上,XmlResourceParser对象处理XML文件的的过程主要是针对不同的状态点处理相应的代码,比如开始分析文档、开始分析标签、分析标签完成等,XmlResourceParser通过调用next方法不断更新当前的状态。
    下面的代码,则是展示如何读取res\xml目录中的XML文件的内容,先在res\xml目录中建立一个xml文件。将AndroidManifest.xml文件复制到res\xml目录中,并改名为android.xml。
    在准备完XML文件后,在onCreate方法中开始读取XML文件的内容,代码如下:
    public void onCreate(Bundle savedInstanceState)
    {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    TextView textView=(TextView)findViewById(R.id.textview);
    StringBuffer sb=new StringBuffer();
    // 获得处理android。xml文件的XmlResourceParser对象
    XmlResourceParser xml=getResources().getXml(R.xml.android);
    try
    {
    //切换到下一个状态,并获得当前状态的类型
    int eventType =xml.next();
    while(true)
    {
    //文档开始状态
    if(eventType == XmlPullParser.START_DOCUMENT)
    {
      Log.d("start_document","start_document");
    }
    //标签开始状态
    else if(eventType ==XmlPullParser.START_TAG)
    {
      Log.d("start_tag",xml.getName());
      //将标签名称和当前标签的深度(根节点的depth是1,第2层节点的depth是2,类推)
      sb.append(xml.getName()+"(depth:"+xml.getDepth()" ");
      //获得当前标签的属性个数
      int count=xml.getAttributeCount();
      //将所有属性的名称和属性值添加到StringBuffer对象中
      for(int i=0;i<count;i++)
      {
       sb.append(xml.getAttributeName(i)+":
       "+xml.getAttributeValue(i)+"");
      }
      sb.append(")\n");
    }
    //标签结束状态
    else if(eventType ==XmlPullParser.END_TAG)
    {
      Log.d("end_tag",xml.getName());
    }
    //读取标签内容状态
    else if(eventType ==XmlPullParser.TEXT)
    {
      Log.d("text","text");
    }
    //文档结束状态
    else if(eventType ==XmlPullParser.END_DOCUMENT)
    {
      Log.d("end_document","end_document");
      //文档分析结束后,退出while循环
      break;
    }
    //切换到下一个状态,并获得当前状态的类型
    eventType =xml.next();

    }
    textView.setText(sb.toString());


    }
      catch(Exception e)  {}
    }
    二、如果想读入文件
    在使用getAssets().open("anhui.xml")返回输人流之后,就可以以此为参数,后面的处理跟普通的java的处理相同
    展开全文
  • Android链接服务器获取图片在此提供三种方法,已通过验证,无误。 方法一: [java] view plain copy public static Bitmap getImage(String path){     try {   ...

     Android链接服务器获取图片在此提供三种方法,已通过验证,无误。

    方法一:

    [java] view plain copy
    1. public static Bitmap getImage(String path){  
    2.       
    3.     try {  
    4.         HttpURLConnection conn = (HttpURLConnection) new URL(path).openConnection();  
    5.         conn.setConnectTimeout(5000);  
    6.         conn.setRequestMethod("GET");  
    7.         System.out.println("tdw1");  
    8.         if(conn.getResponseCode() == 200){  
    9.             InputStream inputStream = conn.getInputStream();  
    10.             Bitmap bitmap = BitmapFactory.decodeStream(inputStream);     
    11.             return bitmap;  
    12.         }  
    13.     } catch (Exception e) {  
    14.         e.printStackTrace();  
    15.     }  
    16.     return null;  
    17. }  

    在第一种方法中,从conn的输入流中获取数据将其转化为Bitmap型数据。

    在功能代码中:

    [java] view plain copy
    1. image.setImageBitmap(getImage("路径"));  
    image为ImageView型控件。


    第二种方法:

    [java] view plain copy
    1. public static Bitmap getImage1(String path){  
    2.       
    3.         HttpGet get = new HttpGet(path);  
    4.         HttpClient client = new DefaultHttpClient();  
    5.         Bitmap pic = null;  
    6.           try {  
    7.            HttpResponse response = client.execute(get);  
    8.            HttpEntity entity = response.getEntity();  
    9.            InputStream is = entity.getContent();  
    10.   
    11.            pic = BitmapFactory.decodeStream(is);   // 关键是这句代  
    12.     } catch (Exception e) {  
    13.         e.printStackTrace();  
    14.     }  
    15.     return pic;  
    16. }  

    这个方法类似上面那个方法。在功能代码中设置是一样的


    第三种方法:

    [java] view plain copy
    1. public static Uri getImage2(String path,File cacheDir){  
    2.         File localFile = new File(cacheDir,MD5.getMD5(path)+path.substring(path.lastIndexOf(".")));  
    3.         if(localFile.exists()){  
    4.             return Uri.fromFile(localFile);  
    5.         }else  
    6.         {  
    7.             HttpURLConnection conn;  
    8.             try {  
    9.                 conn = (HttpURLConnection) new URL(path).openConnection();  
    10.                 conn.setConnectTimeout(5000);  
    11.                 conn.setRequestMethod("GET");  
    12.                 if(conn.getResponseCode() == 200){  
    13.                     System.out.println("tdw");  
    14.                     FileOutputStream outputStream = new FileOutputStream(localFile);  
    15.                     InputStream inputStream = conn.getInputStream();  
    16.                     byte[] buffer = new byte[1024];  
    17.                     int length = 0;  
    18.                     while((length=inputStream.read(buffer))!=-1){  
    19.                         outputStream.write(buffer, 0, length);  
    20.                     }  
    21.                     inputStream.close();  
    22.                     outputStream.close();  
    23.                     return Uri.fromFile(localFile);  
    24.                 }  
    25.             } catch (Exception e) {  
    26.                 // TODO Auto-generated catch block  
    27.                 e.printStackTrace();  
    28.             }  
    29.         }  
    30.         return null;      
    31.     }  

    第三种方法,将从服务器获取的数据存入本地的文件中,如果文件已存在,则不需要从服务器重新获取数据。

    在功能代码中:

    [java] view plain copy
    1. image.setImageURI(getImage2(path, cache));  

    上面代码中设置图片为缓存设置,这样如果图片资源更新了,则需要重新命名文件的名字,这样才能够重新加载新图片。

    [java] view plain copy
    1. cache = new File(Environment.getExternalStorageDirectory(),"cache");  
    2. if(!cache.exists()){  
    3.    cache.mkdirs();  
    4. }  

    这里是设置 缓存图片的路径。

    以上为三种方法。

    展开全文
  • 1、程序,把Assets中的图像显示出来 try { BufferedInputStream bis = new BufferedInputStream(getAssets() .open("a.bmp")); Bitmap bm = BitmapFactory.decodeStream(b...

    1、程序,把Assets中的图像显示出来

    try {
    BufferedInputStream bis = new BufferedInputStream(getAssets()
    .open("a.bmp"));
    Bitmap bm = BitmapFactory.decodeStream(bis);
    imageView01.setImageBitmap(bm);

    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    System.out.println("==========file not found======");
    }

    2、原理:Android中的资源分析
    资源是Android应用程序中重要的组成部分。在应用程序中经常会使用字符串、菜单、图像、声音、视频等内容,都可以称之为资源。通过将资源放到与apk文件中与Android应用程序一同发布,在资源文件比较大的情况下,可以通过将资源作为外部文件来使用,我们将分析如何在Android应用程序中存储这些资源。

    一、资源的存储

    在android中,资源大多都是保存在res目录中,例如布局资源以XML文件的形式保存在res\layout目录中;图像资源保存着res\drawable目录中;菜单资源保存在res\menu目录中。ADT在生成apk文件时,这些目录中的资源都会被编译,然后保存到apk文件中。如果将资源文件放到res\raw目录中,资源将在不编译的情况下放入apk文件中。在程序运行时可以使用InputStream来读取res\raw目录中的资源。

    如果使用的资源文件过大,我们可以考虑将资源文件作为外部文件单独发布。Android应用程序会从手机内存或者SD卡读取这些资源文件。

    二、资源的种类

    从资源文件的类型来划分,我们可以将资源文件划分为XML、图像和其它。以XML文件形式存储的资源可以放在res目录中的不同子目录里,用来表示不同种类的资源;而图像资源会放在res\drawable目录中。除此之外,可以将任意的资源嵌入Androidy应用程序中。比如音频和视频等,一般这些资源放在res\raw目录中。

    表1、 Android支持的资源
    目录 资源类型 描述
    Res\values
    XML
    保存字符串、颜色、尺寸、类型、主题等资源,可以是任意文件名。对于字符串、颜色、尺寸等信息采用
    Key-value形式表示,对于类型、主题等资源,采用其它形式表示
    Res\layout
    XML
    保存布局信息。一个资源文件表示一个View或ViewGroup的布局
    Res\menu
    XML
    保存菜单资源。一个资源文件表示一个菜单(包括子菜单)
    Res\anim
    XML
    保存与动画相关的信息。可以定义帧(frame)动画和补间(tween)动画
    Res\xml
    XML
    在该目录的文件可以是任意类型的XML文件,这些XML文件可以在运行时被读取。
    Res\raw
    任意类型
    在该目录中的文件虽然也会被封装在apk文件中,但不会被编译。在该目录中可以放置任意类型的文件,例如,各种类型的文档、音频、视频文件等
    Res\drawable
    图像
    该目录中的文件可以是多种格式的图像文件,例如,bmp、png、gif、jpg等。在该目录中的图像不需要分辨率非常高,aapt工具会优化这个目录中的图像文件。如果想按字流读取该目录下的图像文件,需要将图像文件放在res\raw目录中。
    assets
    任意类型
    该目录中的资源与res\raw中的资源一样,也不会被编译。但不同的是该目录中的资源文件都不会生出资源ID
    三、资源文件的命名

    每一个资源文件或资源文件中的key-value对都会在ADT自动生成的R类(在R.java文件中)中找到相对应的ID.其中资源文件名或key-value对中的key就是R类中的java变量名。因此,资源文件名好key的命名首先要符合java变量的命名规则。

    除了资源文件和key本身的命名要遵循相应的规则外,多个资源文件和key也要遵循唯一的原则。也就是说,同类资源的文件名或key不能重复。例如,两个表示字符串资源的key不能重复,就算这两个key在不同的XML文件中也不行。

    由于ADT在生成ID时并不考虑资源文件的扩展名,因此,在res\drawable、res\raw等目录中不能存在文件名相同,扩展名不同的资源文件。例如在res\drawable目录不能同时放置icon.jpg和icon.png文件。

    四、资源使用示例

    在Android SDK中不仅提供了大量的系统资源,而且还允许开发人员定制自己的资源。不管是系统资源,还是自定义的资源,一般都会将这些资源放在res目录中,然后通过R类中的相应ID来引用这些资源。接下来将针对于XML类资源的使用进行分析。

    XML资源实际上就是XML格式的文本文件,这些文件必须放在res\xml目录中。可以通过Resources.getXml方法获得处理指定XML文件的XmlResourceParser对象。实际上,XmlResourceParser对象处理XML文件的的过程主要是针对不同的状态点处理相应的代码,比如开始分析文档、开始分析标签、分析标签完成等,XmlResourceParser通过调用next方法不断更新当前的状态。

    下面的代码,则是展示如何读取res\xml目录中的XML文件的内容,先在res\xml目录中建立一个xml文件。将AndroidManifest.xml文件复制到res\xml目录中,并改名为android.xml。

    在准备完XML文件后,在onCreate方法中开始读取XML文件的内容,代码如下:

    public void onCreate(Bundle savedInstanceState)
    {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    TextView textView=(TextView)findViewById(R.id.textview);
    StringBuffer sb=new StringBuffer();
    // 获得处理android。xml文件的XmlResourceParser对象
    XmlResourceParser xml=getResources().getXml(R.xml.android);
    try
    {
    //切换到下一个状态,并获得当前状态的类型
    int eventType =xml.next();
    while(true)
    {
    //文档开始状态
    if(eventType == XmlPullParser.START_DOCUMENT)
    {
    Log.d("start_document","start_document");
    }
    //标签开始状态
    else if(eventType ==XmlPullParser.START_TAG)
    {
    Log.d("start_tag",xml.getName());
    //将标签名称和当前标签的深度(根节点的depth是1,第2层节点的depth是2,类推)
    sb.append(xml.getName()+"(depth:"+xml.getDepth()" ");
    //获得当前标签的属性个数
    int count=xml.getAttributeCount();
    //将所有属性的名称和属性值添加到StringBuffer对象中
    for(int i=0;i<count;i++)
    {
    sb.append(xml.getAttributeName(i)+":
    "+xml.getAttributeValue(i)+"");
    }
    sb.append(")\n");
    }
    //标签结束状态
    else if(eventType ==XmlPullParser.END_TAG)
    {
    Log.d("end_tag",xml.getName());
    }
    //读取标签内容状态
    else if(eventType ==XmlPullParser.TEXT)
    {
    Log.d("text","text");
    }
    //文档结束状态
    else if(eventType ==XmlPullParser.END_DOCUMENT)
    {
    Log.d("end_document","end_document");
    //文档分析结束后,退出while循环
    break;
    }
    //切换到下一个状态,并获得当前状态的类型
    eventType =xml.next();

    }
    textView.setText(sb.toString());


    }
    catch(Exception e) {}
    }

    二、如果想读入文件

    在使用getAssets().open("anhui.xml")返回输人流之后,就可以以此为参数,后面的处理跟普通的java的处理相同。

    转载于:https://my.oschina.net/haquanwen/blog/53977

    展开全文
  • Android资源图片读取机制

    千次阅读 2014-09-28 15:43:05
    在新建一个Android项目时,在res目录下会自动生成几个drawable文件夹,drawable-ldpi,drawable-mdpi,drawable-hdpi,一直以来都对此不太清楚,图片应该放到哪个文件夹下面,有什么不同的影响?以前一直都是干脆再新建...

    在新建一个Android项目时,在res目录下会自动生成几个drawable文件夹,drawable-ldpi,drawable-mdpi,drawable-hdpi,一直以来都对此不太清楚,图片应该放到哪个文件夹下面,有什么不同的影响?以前一直都是干脆再新建一个不带后缀的drawable文件夹,图片都丢进去,现在决定彻底搞清楚这个事儿。

     1、基础知识

    density(密度):简单的说就是一个比例系数,用来将Dip(设备独立像素)转换成实际像素px。具体公式是:

    px = dip*density+0.5f;

    densityDpi:The screen density expressed asdots-per-inch.简单的说就是densityDpi = density*160

      

     drawable文件夹除了这些密度类的后缀,还有例如-en表示英语环境,-port表示用于竖屏等,这里不做讨论,可以参考http://developer.android.com/guide/topics/resources/providing-resources.html

    另附一张官方的屏幕大小与密度的对应表:



     2、为什么要缩放

    为了适应这么多乱七八糟的设备,Android官方就建议大家针对不同密度的设备制作不同的图片:

    36x36 (0.75x) for low-density

     48x48 (1.0xbaseline) for medium-density

     72x72 (1.5x) for high-density

     96x96 (2.0x) for extra-high-density

     180x180 (3.0x) for extra-extra-high-density

     192x192 (4.0x) for extra-extra-extra-high-density(launcher icon only; see note above)

     

     问题就来了,如果你不听建议,就整了一种密度的图片呢?那么当遇到不同密度的手机时,系统就会好(无)心(情)的对你的图进行缩放了,按文档的说法,这是为了你的应用更好看。

    缩放公式:缩放后大小= 图片实际大小 × (手机密度/图片密度)

    其中图片密度由图片所在drawable文件夹的后缀决定

    比如一张100X100的图放在mdpi文件夹里,在hdpi的手机上,缩放后大小= 100 * (1.5/1) = 150

    就成了一张150*150的图片。


    3、android:anyDensity

    (网上有些博客对这个属性的解释是错的,这里特意提一下)

    在AndroidManifest.XML文件里可以设置这么一个属性:<supports-screens android:anyDensity="true"/>

    不设置的话默认为true。

    按文档的说法(http://developer.android.com/guide/practices/screens_support.html),这个值如果为true,缩放机制为预缩放(pre-scaling),如果为false,缩放机制为自动缩放(auto-scaling),区别是预缩放是在读取时缩放,自动缩放时在绘制的时候缩放,从速度来说预缩放要快一些。另外还有一个很重要的区别,就是如果<supports-screensandroid:anyDensity="false"/>,应用在请求屏幕参数时,系统会欺骗应用,告诉它你现在跑在一个density为1的手机上,而不管手机实际density是多少,比如实际手机是hdpi,尺寸480*800,系统会告诉应用屏幕尺寸是320(400/1.5)*533(800/1.5),然后当应用将图片绘制到(10,10)到(100,100)的区域时,系统会将其转换到(15,15)到(150,150),这时如果你去直接操作这些缩放后的图,就会出些不可预期的问题。总之就是建议不要把这个属性设为false。

    按我的个人理解,这个false就是告诉系统这个应用不支持多分辨率,于是系统就认为你只支持默认分辨率(mdpi),系统就会给你虚拟一个mdpi的设备,让你显示在上面,系统再从这上面拉伸或者缩小到实际设备上。这样既速度慢又效果不好,所以就不推荐。


     4、各目录读取优先级

    假设项目内有如下drawable目录:

    drawable

    drawable-nodpi

    drawable-ldpi

    drawable-mdpi

    drawable-hdpi

    drawable-xhdpi.

     (如果不想系统对图片进行缩放,可以把图片放到drawable-nodpi目录下,从该目录读的图片系统不会进行任何缩放。)

    (由下文可知,不带后缀的drawable目录下的图片按照drawable-mdpi处理.)

     

    如果这些目录下都可能有一张同名图片,那系统该读哪一张呢?

    毋庸置疑,如果手机密度相同的相应的密度目录下有该图片,那就是它了,如果没有呢?

    跟踪源码看看系统是如何选择图片的(基于android4.4.2):

     

    ImageView.java:

    setImageResource()

    resolveUri() 

     

    Resources.java:

    getDrawable()

    getValue()

     

    AssetManager.java:

    getResourceValue()

    native loadResourceValue()

     

    frameworks/base/core/jni/android_util_AssetManager.cpp:

    android_content_AssetManager_loadResourceValue()

     

    frameworks/base/libs/androidfw/AssetManager.cpp:

    AssetManager::getResources()

    AssetManager::getResTable()

     

    frameworks/base/libs/androidfw/ResourceTypes.cpp:

    ResTable::getResource()

    ResTable::getEntry()

     

    ssize_t ResTable::getEntry(
       const Package* package, int typeIndex, int entryIndex,
       const ResTable_config* config,
       const ResTable_type** outType, const ResTable_entry** outEntry,
       const Type** outTypeClass) const
    {
       ********省略*******
       
       const size_t NT = allTypes->configs.size();
       for (size_t i=0; i<NT; i++) {
           const ResTable_type* const thisType = allTypes->configs[i];
           if (thisType == NULL) continue;
           
           ResTable_config thisConfig;
           thisConfig.copyFromDtoH(thisType->config);
     
              ********省略*******
           
           if (type != NULL) {
               // Check if this one is less specific than the last found.  If so,
               // we will skip it.  We checkstarting with things we most care
               // about to those we least care about.
               if(!thisConfig.isBetterThan(bestConfig, config)) {  //就是这里
                    TABLE_GETENTRY(ALOGI("Thisconfig is worse than last!\n"));
                    continue;
               }
           }
            
           type = thisType;
           offset = thisOffset;
           bestConfig = thisConfig;
           TABLE_GETENTRY(ALOGI("Best entry so far -- using it!\n"));
           if (!config) break;
        }
         ********省略*******
       return offset + dtohs(entry->size);
    }

     

    ResTable_config::isBetterThan()

     

    bool ResTable_config::isBetterThan(const ResTable_config& o,
    
            const ResTable_config* requested) const {
    
        if (requested) {
    
              **************
    
    
            if (screenType || o.screenType) {
    
                if (density != o.density) {
    
                    // density is tough.  Any density is potentially useful
    
                    // because the system will scale it.  Scaling down
    
                    // is generally better than scaling up.
    
                    // Default density counts as 160dpi (the system default)
    
                    // TODO - remove 160 constants
    
                    int h = (density?density:160);
    
                    int l = (o.density?o.density:160);
    
                    bool bImBigger = true;
    
                    if (l > h) {
    
                        int t = h;
    
                        h = l;
    
                        l = t; 
    
                        bImBigger = false;
    
                    }
    
    
    
                    int reqValue = (requested->density?requested->density:160);
    
                    if (reqValue >= h) {
    
                        // requested value higher than both l and h, give h
    
                        return bImBigger;
    
                    }
    
                    if (l >= reqValue) {
    
                        // requested value lower than both l and h, give l
    
                        return !bImBigger;
    
                    }
    
                    // saying that scaling down is 2x better than up
    
                    if (((2 * l) - reqValue) * h > reqValue * reqValue) {
    
                        return !bImBigger;
    
                    } else {
    
                        return bImBigger;
    
                    }
    
                }
    
    
    
                ***********
            }
    
    
    
        }
    
        return isMoreSpecificThan(o);
    
    }
    


    关键部分已用红字标明,在多个drawable下都有同名图片时,一个资源ID对应不止一个图片,在getEntry里面就有一个循环,用isBetterThan()函数在循环里把最合适的图片选出来。

    可以看见,如果该图片没有指明density,density就默认为160,这也是drawable文件夹下的图片被默认为mdpi的原因。

    在isBetterThan函数里,density是当前资源的密度,o.density是之前的循环中已有的最合适的资源的密度,reqValue则是请求密度。

    三个if,

    第一个if:如果density和o.density都小于reqValue,那么大的那个比较合适

    第二个if:   如果density和o.density都大于reqValue,那么小的那个比较合适

    第三个if:   如果reqValue大小在density和o.density之间,先判断

     if(((2 * l) - reqValue) * h > reqValue * reqValue)

    这个判断大意就是请求密度和较小的密度相差很小而与较大的一个密度相差很大。那么就认为较小的密度更合适。

     

    测试环境: 模拟器+Android4.4.2,其中xh和xxh是用真机+Android4.4.2测的;其中ldpi除Android4.4.2外也用Android2.3.1,hdpi除Android4.4.2外也用了Android2.1,结果并无不同。

    测试目录:drawable-ldpi,drawable-mdpi,drawable-hdpi,drawable-xhdpi,drawable-nodpi,drawable

    测试结果():

    怎么drawable-nodpi有时候在前面有时候在后面?附两处源码你就明白了

    frameworks/base/include/androidfw/ResourceTypes.h:

        enum {
            DENSITY_DEFAULT = ACONFIGURATION_DENSITY_DEFAULT,
            DENSITY_LOW =ACONFIGURATION_DENSITY_LOW,
            DENSITY_MEDIUM =ACONFIGURATION_DENSITY_MEDIUM,
            DENSITY_TV = ACONFIGURATION_DENSITY_TV,
            DENSITY_HIGH =ACONFIGURATION_DENSITY_HIGH,
            DENSITY_XHIGH = ACONFIGURATION_DENSITY_XHIGH,
            DENSITY_XXHIGH =ACONFIGURATION_DENSITY_XXHIGH,
            DENSITY_XXXHIGH =ACONFIGURATION_DENSITY_XXXHIGH,
            DENSITY_NONE =ACONFIGURATION_DENSITY_NONE
        };

    frameworks/native/include/android/configuration.h:

        ACONFIGURATION_DENSITY_DEFAULT = 0,
        ACONFIGURATION_DENSITY_LOW = 120,
        ACONFIGURATION_DENSITY_MEDIUM = 160,
        ACONFIGURATION_DENSITY_TV = 213,
        ACONFIGURATION_DENSITY_HIGH = 240,
        ACONFIGURATION_DENSITY_XHIGH = 320,
        ACONFIGURATION_DENSITY_XXHIGH = 480,
        ACONFIGURATION_DENSITY_XXXHIGH = 640,
        ACONFIGURATION_DENSITY_NONE = 0xffff,

     

    可见drawable-nodpi目录下的图片密度值为0xffff,即65535,带入判断一算,结果正如测试所得。

    无图无真相,所以贴一张hdpi环境的测试图:

    想要知道会读取到哪张图,可以这样:

    TypedValue typedValue = new TypedValue();
    getResources().getValue(R.drawable.test,typedValue,true);
    //然后typedValue.string的值就是实际读取的图片路径

     

     

     

     

    展开全文
  • Android开发之获取相册照片和获取拍照照片

    万次阅读 多人点赞 2013-05-17 17:36:00
    Android的开发过程中,我们可能会读取手机里面的照片或者通过相机拍摄获取照片,这是两种常用的获取图片的方式,在做项目过程中也会经常遇到,下面来介绍一下这两种获取方式.. 1.从本地相册获取照片: 一般就是...
  • android华为手机读取本地文件夹图片获取path路径null,求指导
  • Android 读取Assets中图片

    万次阅读 2011-06-01 10:56:00
    bgimg0 = getImageFromAssetsFile("Cat_... * 从Assets中读取图片 */ private Bitmap getImageFromAssetsFile(String fileName) { Bitmap image = null; AssetManager am = getResources().getAs
  • Android 如何获取surfaceview上的图片 Canvas canvas=holder.lockCanvas(); bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.test); canvas.drawBitmap(bitmap, 0, 0, null); holder....
  • android 根据图片路径获取图片缩略图

    千次阅读 2018-04-19 17:48:22
    * 根据指定的图像路径和大小来获取缩略图 * * @param path 图像的路径 * @param maxWidth 指定输出图像的宽度 * @param maxHeight 指定输出图像的高度 * @return 生成的缩略图 */ public static Bitm...
  • Android 10 获取相册图片失败

    千次阅读 2020-06-09 09:49:22
    Android10获取相册图片失败
  • 读取本地项目里的资源图片,但又不能用到R文件。总结以下几种读取Bitmap的方法:1、以文件流的方式,假设sdcard里面有a.png图片FileInputStream fs = new FileInputStream("/sdcard/test.png");Bitmap ...
  • android 读取本地图片生成 bitmap

    万次阅读 2019-01-30 14:10:51
    读取本地项目里的资源图片,但又不能用到 R 文件。  现总结以下几种读取 Bitmap 的方法。  1.以文件流的方式,假设在 sdcard 下有 test.png 图片 FileInputStream fis = new FileInputStream("/...
  • Android 获取指定文件目录下的图片

    千次阅读 2017-05-07 15:37:37
    //selection: 指定查询条件 String selection = MediaStore.Images.Media.DATA + " like '%Camera%'"; //设定查询目录 String path="/mnt/sdcard/youpicpath"; //定义selectionArgs: String[] selectionArgs = {...
  • Android获取res目录下图片的uri

    千次阅读 2018-06-14 20:37:47
    Uri.parse("android.resource://" + getApplicationContext().getPackageName() + "/" +R.mipmap.koko)
  • Android-从音频文件中获取专辑图片

    千次阅读 2016-07-29 17:34:44
    如何获取本地音频文件的专辑图片呢?不多说了,直接上代码吧:public static Bitmap setArtwork(Context context, String url, ImageView ivPic) { Uri selectedAudio = Uri.parse(url); MediaMetadataRetriever ...
  • 求大神助攻啊, **android 开发中怎么替换一段视频的第一帧图像** ,请给个思路,先谢过了!
  • android 获取资源文件 r.drawable中的图片转换为drawable、bitmap 转载自http://cfanz.cn/index.php?c=article&a=read&id=141146 1、 Resources resources = mContext.getResources(); Drawable ...
  • android获取图片的旋转角度

    万次阅读 2014-08-20 21:20:54
    public static int getExifOrientation(String filepath) { int degree = 0; ExifInterface exif = null; try { exif = new ExifInterface(filepath); } catch (IOException ex) { Log
  • Android--ImageView读取本地路径图片

    千次阅读 2019-04-12 19:01:47
    对于一些比较大且需要长期保存的的图片,我们可能会选择把它存在Sdcard上,而看了网上一些对于Sdcard路径图片读取,总结了两个小方法 将路径初始化为Uri imageview.setImageURI(Uri.fromFile( new File(这里填路径...
  • ![图片说明](https://img-ask.csdn.net/upload/201709/13/1505287531_853527.png) 我用的是Android studio
1 2 3 4 5 ... 20
收藏数 220,801
精华内容 88,320
关键字:

android怎么读取图片