读入大图片时out of memory问题解决

参考网址:http://stackoverflow.com/questions/477572/android-strange-out-of-memory-issue-while-loading-an-image-to-a-bitmap-object

从外部读入图片的方法:
1. FileInputStream is = new FileInputStream(imageDir);
   Drawable image = Drawable.createFromStream(is, null);
2. Drawable image = Drawable.createFromPath(imageDir);
由于图片多大,上面两种用法都会产生内存溢出的问题。
解决方法如下:
File imageFile = new File(imageDir);
Drawable image = decodeFile(imageFile);

 private Drawable decodeFile(File f) {
        try {
            // Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f), null, o);

            // The new size we want to scale to
            final int REQUIRED_SIZE = 400;

            // Find the correct scale value. It should be the power of 2.
            int scale = 1;
            while (o.outWidth / scale / 2 >= REQUIRED_SIZE
                    && o.outHeight / scale / 2 >= REQUIRED_SIZE)
                scale *= 2;

            // Decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(f),
                    null, o2);
            ImageView iv = new ImageView(context);
            iv.setImageBitmap(bitmap);
            return iv.getDrawable();
        } catch (FileNotFoundException e) {

        }
        return null;
    }

// -------------------压缩图片的方法
//参考网址:http://www.cnblogs.com/leizhenzi/archive/2011/05/14/2046431.html
//      public Drawable createThumbnails(String url) {
//        BitmapFactory.Options options = new BitmapFactory.Options();
//        options.inJustDecodeBounds = true;
//        Bitmap bitmap = BitmapFactory.decodeFile(url, options); // 此时返回bm为空
//
//        options.inJustDecodeBounds = false;
//
//        // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
//
//        int be = (int) (options.outHeight / (float) 2);
//        if (be <= 0)
//            be = 1;
//
//        options.inSampleSize = be;
//
//        // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
//
//        bitmap = BitmapFactory.decodeFile(url, options);
//        int w = bitmap.getWidth();
//        int h = bitmap.getHeight();
//        ImageView iv = new ImageView(context);
//        iv.setImageBitmap(bitmap);
//
//        return iv.getDrawable();
//    }

Options中有个属性inJustDecodeBounds
如果该值设为true那么将不返回实际的bitmap不给其分配内存空间而里面只包括一些解码边界信息即图片大小信息,那么相应的方法也就出来了,通过设置inJustDecodeBounds为true,获取到outHeight(图片原始高度)和 outWidth(图片的原始宽度),然后计算一个inSampleSize(缩放值),然后就可以取图片了,这里要注意的是,inSampleSize 可能小于0,必须做判断。也就是说先将Options的属性inJustDecodeBounds设为true,先获取图片的基本大小信息数据(信息没有保存在bitmap里面,而是保存在options里面),通过options.outHeight和 options. outWidth获取的大小信息以及自己想要到得图片大小计算出来缩放比例inSampleSize,然后紧接着将inJustDecodeBounds 设为false,就可以根据已经得到的缩放比例得到自己想要的图片缩放图了。

另外两篇可供参考的文章
http://zhiweiofli.iteye.com/blog/905066
http://blog.csdn.net/liaoxingliao/article/details/6937168

http://blog.csdn.net/sjf0115/article/details/7366746

http://www.cnblogs.com/leizhenzi/archive/2011/05/14/2046431.html

posted @ 2012-05-07 15:31  日光之下无新事  阅读(3667)  评论(0编辑  收藏  举报