Android知识总结:Universal-Imageloader学习笔记4 使用Universal-Imageloader管理本地图片

ImageLoader管理本地图片

前面我们讨论了ImageLoader在图片下载与缓存中的一些使用方法,那么为什么我们要用ImageLoader管理本地图片呢?
考虑以下一些情况
在App中,我们常常会进行位图的处理,如果我们需要将图片生成的位图保存,是否能结合到我们的图片框架中?最近项目需要将一张位图做模糊处理,这样的逐点操作非常消耗内存和时间,如果我们直接将处理好的位图压缩并存储在本地,下次打开时就不需要再次处理。
我们经常需要下载很多图片,假如我们要做一个网络相册,用户想修改相册中的一些图片,修改完后要上传。但是我们知道,ImageLoader的硬盘缓存命名并非标准的图片格式,我们无法预览和上传。所以我们必须知道这些图片的存储位置,然后将其拷贝出来,将文件名改成我们服务器规定的命名格式,然后再上传。
综上,我们统一管理图片的各种路径和命名,这样ImageLoder不仅是一个图片加载框架,而完全变成了App的图片管理框架。根据目前的需要,添加了两个功能,日后再不断完善。
结合昨天写的拍照裁剪相关的博文,我们在此打造一个功能比较全面的图片管理demo。

包含功能

1.ImageLoader框架的所有功能
2.图片的拍照、选取及裁剪
3.对拍照图片进行处理的,并将处理结果保存到本地,同时使用ImageLoader加载这种图片
4.根据Uri将网络图片的硬盘缓存文件获取到并拷贝到我们的指定路径下,指定文件命名

其中前两条可以参考以前的博文,今天主要实现了后面两条功能。
代码链接: http://download.csdn.net/detail/lidec/9360771
项目链接: https://git.oschina.net/vonchenchen/ImageLoaderCacheDemo.git

主要流程

文件结构管理

/**
 * Created by vonchenchen on 2015/12/11 0011.
 */
public class ImageLoaderManager {

    //ImageView 的文件缓存
    public final static String FILE_IMAGELOADER_CACHE = Environment
            .getExternalStorageDirectory().getAbsolutePath()
            + "/vonchenchen/ImageLoaderCache/";

    //保存裁剪后照片的路径
    public final static String FILE_SAVEPATH = Environment
            .getExternalStorageDirectory().getAbsolutePath()
            + "/vonchenchen/Portrait/";

    //保存直接拍照后未经剪裁照片的路径
    public final static String FILE_SAVEPATH_CAMERA = Environment
            .getExternalStorageDirectory().getAbsolutePath()
            + "/vonchenchen/Camera/";

    //保存经过模糊处理后的图片路径
    public final static String FILE_SAVEPATH_FUZZY = Environment
            .getExternalStorageDirectory().getAbsolutePath()
            + "/vonchenchen/Fuzzy/";

    //使用ImageLoader下载后需要上传的图片,单独拷贝到这个目录下,并将文件名修改为相应的格式
    public final static String FILE_SAVEPATH_UPLOAD = Environment
            .getExternalStorageDirectory().getAbsolutePath()
            + "/vonchenchen/Upload/";

    //裁剪后照片的前缀名  文件名:FILE_SAVENAME + timeStamp + ".jpg"
    public final static String FILE_SAVENAME_CROP = "vonchenchen";
    //直接拍照后照片的前缀名   文件名:FILE_SAVENAME_CAMERA + timeStamp + ".jpg"/other
    public final static String FILE_SAVENAME_CAMERA = "vonchenchen";
}


管理生成的位图

分析见注释
                    //解压图片
                    protraitBitmap = ImageUtils.convertToBitmap(protraitPath, 200, 200);
                    //将位图进行处理
                    protraitBitmap = BlurUtil.blurBitmap(protraitBitmap, MainActivity.this);
                    //将处理结果压缩为jpeg,写入指定文件
                    protraitUri = saveCroppedImage(protraitBitmap, "test");

                    //用ImageLoader加载这个文件  此处没有知道option,默认不使用内存缓存,可以根据实际情况进行调整
                    ImageLoader.getInstance().displayImage(protraitUri.toString(), mImageView, new ImageLoadingListener() {
                        @Override
                        public void onLoadingStarted(String s, View view) {
                        }
                        @Override
                        public void onLoadingFailed(String s, View view, FailReason failReason) {
                        }
                        @Override
                        public void onLoadingComplete(String s, View view, Bitmap bitmap) {
                            //clearDocument(FILE_SAVEPATH_FUZZY);
                        }
                        @Override
                        public void onLoadingCancelled(String s, View view) {
                        }
                    });
                }

管理下载缓存

ImageLoader下载后的图片命名是使用FileNameGenerator接口来设置,默认是Uri的HashCode。所以我们可以打开ImageLoader的缓存文件夹进行查看,里面的文件都是数字,但是由于没有后缀名,所以手机并不能识别。我们可以尝试给这些文件加个后缀,比如如果下载的是jpeg图,那么就加个.jpg,我们就会发现图片可以正常显示。找到这个图片,了解了其命名是用Uri的hashCode时,就可以获取图片的路径,此时我们即可将图片拷贝到另一个用于管理图片的文件中,并且修改其命名。由于ImageLoader中的硬盘缓存可能被回收,所以如果我们可能需要这张图,就在其下载完毕后立即拷贝。

                        //获取图片在硬盘缓存上的路径
                        String path = getImageLoaderDiskCacheImageName(uriStr, new HashCodeFileNameGenerator());
                        System.out.print(path);

                        //将图片从ImageView维护的硬盘缓存中取出,拷贝到我们指定的路径下
                        File file = copyToUpLoadFileAndRename(path, "upload.jpg");
                        //获取当前图片,这种常用于下载后上传,需要知道图片路径
                        String uploadPath = file.getAbsolutePath();


获取文件名
    /**
     * 获取ImageLoader的硬盘缓存中对应的路径
     * @param uriStr      图片资源uri
     * @param generator   给图片设置名字的generator,需要和config的config中设置的generator一样
     * @return
     */
    private String getImageLoaderDiskCacheImageName(String uriStr, FileNameGenerator generator){
        String name = generator.generate(uriStr);
        String path = ImageLoaderManager.FILE_IMAGELOADER_CACHE + name;
        return path;
    }

拷贝文件
    /**
     * 将图片从ImageLoader的硬盘缓存路径拷贝到上传路径,并指定新的文件名
     * 复制成功返回复制的文件
     * @param path     源路径
     * @param newName  我们指定的文件名
     */
    public File copyToUpLoadFileAndRename(String path, String newName){
        File src = new File(path);
        File des = new File(ImageLoaderManager.FILE_SAVEPATH_UPLOAD + newName);

        String savePath = "";
        String storageState = Environment.getExternalStorageState();
        if (storageState.equals(Environment.MEDIA_MOUNTED)) {
            savePath = ImageLoaderManager.FILE_SAVEPATH_UPLOAD;
            File savedir = new File(savePath);
            if (!savedir.exists()) {
                savedir.mkdirs();
            }
        }

        if(copyToAnotherDocument(src, des) != -1){
            return des;
        }else{
            return null;
        }
    }
    /**
     * 将一个文件拷贝到指定文件目录下,并修文件名
     * @param src
     * @param des
     */
    private int copyToAnotherDocument(File src, File des){
        //long time=new Date().getTime();
        int length=1024*10;
        try {
            FileInputStream in=new FileInputStream(src);
            FileOutputStream out=new FileOutputStream(des);
            byte[] buffer=new byte[length];
            while(true){
                int ins=in.read(buffer);
                if(ins==-1){
                    in.close();
                    out.flush();
                    out.close();
                    //return new Date().getTime()-time;
                    return 1;
                }else
                    out.write(buffer,0,ins);
                }
        }catch (Exception e){
        }finally {
        }
        return -1;
    }


这样,无论是网络加载的图片还是我们自己生成的图片,都被我们抓住了。需要注意的是,使用下载时,我们可以灵活使用option配置ImageLoader的任务,根据不同的情景使确定是否使用内存缓存以及硬盘缓存。







你可能感兴趣的:(android,图片上传,ImageLoader,图片管理,三级缓存)