读取assets目录下面的图片

最近学习一个仿微信的即时通信,最后在关于获取assets目录下的表情图片时发现一点小问题,不知道怎么去获取,后来看了看相关的博客,实现了自己的思路,那么这里就来看看我是怎么一步一步来填坑的。

这是我最终需要实现的效果图:
读取assets目录下面的图片_第1张图片

但是现在资源文件是这样的:

读取assets目录下面的图片_第2张图片

所以我们需要将所有的图片加载到一个集合,因为效果图里面的GridView适配器需要数据源。不过读取assets目录下面的资源文件需要提供路径,我们可以通过AssetManager类来访问这些文件。 我们先看看两个API(看不懂没有关系,后面马上就要用了,测试几次就明白了):

1.文件读取方式
AssetManager.open(String filename),返回的是一个InputSteam类型的字节流,这里的filename必须是文件,而不能是文件夹,AssetManager打开资源文件的open方法是一个重载方法,可以添加一个打开方式的int参数,根据参数不同可做相应操作。具体请看官方文档http://web.mit.edu/clio/MacData/afs/sipb/project/android/docs/reference/android/content/res/AssetManager.html

2.资源文件是可以存在文件夹以及子目录
public final String[]list(String path),返回当前目录下面的所有文件以及子目录的名称。可以通过递归遍历整个文件目录,实现所有资源文件的访问。String[] Array of strings, one for each asset. These file names are relative to ‘path’. You can open the file by concatenating ‘path’ and a name in the returned string (via File) and passing that to open().

知道API了,我们接下来获取所有emoji文件夹下面的表情图片,并将第一张图片加载到一个ImageView上面,看代码:

布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:gravity="center"
    android:orientation="vertical">


    <ImageView 
        android:id="@+id/imageview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher"/>

LinearLayout>

Java代码:

package com.example.test;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;

public class MainActivity extends Activity {


    private ImageView ivimage;
    private List emojidata = new ArrayList();
    int i = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ivimage = (ImageView) findViewById(R.id.imageview);
        deepFile(this,"emoji");
        Log.i("tag", "图片数量:"+emojidata.size());
    }

    public void deepFile(Context ctxDealFile, String path) {
        try {
        //获取指定目录下的所有文件名称
            String str[] = ctxDealFile.getAssets().list(path);
            //emoji文件夹下面有两个文件,所有该数组的长度为1,str[0]是default文件夹,str[1]是xml文件;
            if (str.length > 0) {//如果是目录
                for (String string : str) {
                    path = path + "/" + string;
                    Log.i("tag", "路径:"+path+"文件长度:"+str.length);
                    deepFile(ctxDealFile, path);
                }
            } else {//如果是文件
            //非指定类型的话直接返回
                if(!path.endsWith(".png")){
                    return;
                }
                Log.i("tag", "路径:"+path+str.length);
                i++;
                if(i==1)
                ivimage.setImageBitmap(getImageFromAssetsFile(path));
                emojidata.add(getImageFromAssetsFile(path));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 从Assets中读取图片  
     * @param fileName
     * @return
     */
      private Bitmap getImageFromAssetsFile(String fileName)  
      {  
          Bitmap image = null;  
          AssetManager am = getResources().getAssets();  
          try  
          {  
              InputStream is = am.open(fileName);  
              image = BitmapFactory.decodeStream(is);  
              is.close();  
          }  
          catch (IOException e)  
          {  
              e.printStackTrace();  
          }  

          return image;  

      }
}

最后我们得到了所有的图片,一共一百二十五张,并把第二张图片显示出来了!
读取assets目录下面的图片_第3张图片
读取assets目录下面的图片_第4张图片

那么我们接着加载预先收藏的表情图片看看有什么问题?

读取assets目录下面的图片_第5张图片

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ivimage = (ImageView) findViewById(R.id.imageview);
        String[] listFileSticker = null;
        try {
        //获取第一层的文件集合
            listFileSticker = this.getAssets().list("sticker");

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //加载第二个文件夹的图片
        deepFile(ctxDealFile,listFileSticker[1]);
        Log.i("tag", "图片数量:"+emojidata.size());
    }

读取assets目录下面的图片_第6张图片
读取assets目录下面的图片_第7张图片

这里说明我们根本没有得到图片,问题是出在哪里呢?
也就是说我们只能通过路径来加载文件夹下面的图片,直接调用文件是不行的!

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ivimage = (ImageView) findViewById(R.id.imageview);
        deepFile(ctxDealFile,"sticker/lt");//路径:"sticker/lt"
        Log.i("tag", "图片数量:"+emojidata.size());
    }

读取assets目录下面的图片_第8张图片
读取assets目录下面的图片_第9张图片

如果我们不是加载文件夹,而是直接加载assets下面的图片呢?
很简单:
读取assets目录下面的图片_第10张图片

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ivimage = (ImageView) findViewById(R.id.imageview);     ivimage.setImageBitmap(getImageFromAssetsFile("ajmd_s_pressed.png"));
    }

/**
     * 从Assets中读取图片  
     * @param fileName
     * @return
     */
      private Bitmap getImageFromAssetsFile(String fileName)  
      {  
          Bitmap image = null;  
          AssetManager am = getResources().getAssets();  
          try  
          {  
              InputStream is = am.open(fileName);  
              image = BitmapFactory.decodeStream(is);  
              is.close();  
          }  
          catch (IOException e)  
          {  
              e.printStackTrace();  
          }  

          return image;  

      }

读取assets目录下面的图片_第11张图片

源码比较简单,已经写出来了,最后还是把工具类贴出来:

package com.weixing.myofwechat.utils;
/**
 * 管理地址的类
 * @author Administrator
 *
 */
public class Const 
{
    /**
     * 需要加载Assets文件里面的emoji文件
     */
    public static final String ASSETS_TYPE_EMOJI = "emoji";
    /**
     * 需要加载Assets文件里面的ajmd文件
     */
    public static final String ASSETS_TYPE_AJMD = "sticker/ajmd";
    /**
     * 需要加载Assets文件里面的lt文件
     */
    public static final String ASSETS_TYPE_LT = "sticker/lt";
    /**
     * 需要加载Assets文件里面的xxy文件
     */
    public static final String ASSETS_TYPE_XXY = "sticker/xxy";
}
package com.weixing.myofwechat.utils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.util.Log;
/**
 * 工具类
 * @author Administrator
 *
 */
public class Utis 
{
    private static String tag = "com.weixing.myofwechat.utils";
    private static List bitmapData = new ArrayList();

    /**
     * 加载assets下指定文件的Bitmap集合
     * @param context
     * @param path
     * @return
     */

    public static List scanSpecifyFile(Context context,String path)
    {

        try {
            String str[] = context.getAssets().list(path);
            if (str.length > 0) {//如果是目录
                File file = new File("/data/" + path);
                file.mkdirs();
                for (String string : str) 
                {
                    path = path + "/" + string;
                    System.out.println("zhoulc:\t" + path);
                    scanSpecifyFile(context, path);
                    path = path.substring(0, path.lastIndexOf('/'));
                }
            } else 
            {//如果是文件
                if(!path.endsWith(".png"))
                {   //如果不是指定的文件类型
                    return bitmapData;
                }
                Log.i("tag", "path:"+path+str.length);
                bitmapData.add(getBitmapFromAssetsFile(context,path));
            }
        } catch (IOException e) 
        {
            e.printStackTrace();
        }
        return bitmapData;

    }
    /**
     * 从Assets中读取图片位图
     * @param path
     * @return
     */
    private static Bitmap getBitmapFromAssetsFile(Context context,String fileName) 
    {
        Bitmap image = null;  
          AssetManager am = context.getResources().getAssets();  
          try  
          {  
              InputStream is = am.open(fileName);  
              image = BitmapFactory.decodeStream(is);  
              is.close();  
          }  
          catch (IOException e)  
          {  
              e.printStackTrace();  
          }  

          return image; 
    }
    /**
     * 处理失真图形生成圆形头像,
     * 失真图形指如资源文件生成的Bitmap
     * @param context 上下文对象
     * @param idsource ID资源
     * @param min 圆形头像半径
     * @return Bitmap
     */
    public static Bitmap createCircleImage(Context context,int idsource, int min) 
    {

        Bitmap source = BitmapFactory.decodeResource(context.getResources(), idsource);
        final Paint paint = new Paint();
        paint.setAntiAlias(true);
        // 注意一定要用ARGB_8888
        Bitmap target = Bitmap.createBitmap(min, min, Config.ARGB_8888);
        Bitmap src = Bitmap.createScaledBitmap(source, min, min, false);
        // 产生一个同样大小的画布
        Canvas canvas = new Canvas(target);
        // 首先绘制圆形
        canvas.drawCircle(min / 2, min / 2, min / 2, paint);
        // 使用SRC_IN
        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        // 绘制图片
        canvas.drawBitmap(src, 0, 0, paint);
        return target;
        }

}

参考文章:
http://blog.sina.com.cn/s/blog_5da93c8f0100wvcr.html
http://my.oschina.net/zhoulc/blog/118693

你可能感兴趣的:(工具类)