android加载Bitmap优化

来源:互联网 发布:nuitka linux 编辑:程序博客网 时间:2024/05/16 01:57

        程序加载大图时容易出现内存溢出。一般当加载过大图片时同过将 options.inJustDecodeBounds = true;使程序,并不真正的将bitmap加载到内存,但可以获得bitmap的一些信息,来对图片进行处理,来减少内存溢出。

   可获得的一些信息: 

     options.outWidth 为图片的宽度

     options.outHeight 为图片的高度

    图片的分辨率:

        options.outWIdth * options.outHeight

    图片的缩放比:

       opitons.simpleSize 该参数一般为 2 的平方或8的倍数。主要是通过调整它来达到目的。如 options.simpleSize = 2; 时,表示图片的款和高各缩小1/2;

    

   Bitmap.Config :

       ARGB_8888  表示 一个像素占4个字节

             RGB_565  表示 一个像素占1个字节 

      

    
 public static Bitmap makeBitmap(int minSideLength, int maxNumOfPixels,            Uri uri) {        try {
            BitmapFactory.Options options = new BitmapFactory.Options();

            // 不加载到内存
            options.inJustDecodeBounds = true;
            BitmapManager.instance().decodeFileDescriptor(fd, options);
           
            options.inSampleSize = computeSampleSize(
                    options, minSideLength, maxNumOfPixels);
            options.inJustDecodeBounds = false;

            options.inDither = false;
            options.inPreferredConfig = Bitmap.Config.ARGB_8888;
            return BitmapManager.instance().decodeFileDescriptor(fd, options);
        } catch (OutOfMemoryError ex) {
            Log.e(TAG, "Got oom exception ", ex);
            return null;
        }
    }
           
   private static int computeInitialSampleSize(BitmapFactory.Options options,            int minSideLength, int maxNumOfPixels) {        double w = options.outWidth;        double h = options.outHeight;        int lowerBound = (maxNumOfPixels == IImage.UNCONSTRAINED) ? 1 :                (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));        int upperBound = (minSideLength == IImage.UNCONSTRAINED) ? 128 :                (int) Math.min(Math.floor(w / minSideLength),                Math.floor(h / minSideLength));        if (upperBound < lowerBound) {            // return the larger one when there is no overlapping zone.            return lowerBound;        }        if ((maxNumOfPixels == IImage.UNCONSTRAINED) &&                (minSideLength == IImage.UNCONSTRAINED)) {            return 1;        } else if (minSideLength == IImage.UNCONSTRAINED) {            return lowerBound;        } else {            return upperBound;        }    }
public static int computeSampleSize(BitmapFactory.Options options,            int minSideLength, int maxNumOfPixels) {        int initialSize = computeInitialSampleSize(options, minSideLength,                maxNumOfPixels);        int roundedSize;        if (initialSize <= 8) {            roundedSize = 1;            while (roundedSize < initialSize) {                roundedSize <<= 1;            }        } else {            roundedSize = (initialSize + 7) / 8 * 8;        }        return roundedSize;    }