Android使用BitmapFactory.Options解决加载大图片内存溢出问题

由于Android对图片使用内存有限制,若是加载几兆的大图片便内存溢出。Bitmap会将图片的所有像素(即长x宽)加载到内存中,如果图片分辨率过大,会直接导致内存溢出(java.lang.OutOfMemoryError),只有在BitmapFactory加载图片时使用BitmapFactory.Options对相关参数进行配置来减少加载的像素。

1、设置缩放大小对图片作处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public Bitmap getBitmapFromFile ( File dst, int width, int height ) {
    if ( null != dst && dst. exists ( ) ) {
        BitmapFactory. Options opts = null ;
        if (width > 0 && height > 0 ) {
            opts = new BitmapFactory. Options ( ) ;
            opts. inJustDecodeBounds = true ;
            BitmapFactory. decodeFile (dst. getPath ( ), opts ) ;
            // 计算图片缩放比例
            final int minSideLength = Math. min (width, height ) ;
            opts. inSampleSize = computeSampleSize (opts, minSideLength,
                    width * height ) ;
            opts. inJustDecodeBounds = false ;
            opts. inInputShareable = true ;
            opts. inPurgeable = true ;
        }
        try {
            return BitmapFactory. decodeFile (dst. getPath ( ), opts ) ;
        } catch ( OutOfMemoryError e ) {
            e. printStackTrace ( ) ;
        }
    }
    return null ;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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 ;
}

private static int computeInitialSampleSize (BitmapFactory. Options options,
        int minSideLength, int maxNumOfPixels ) {
    double w = options. outWidth ;
    double h = options. outHeight ;

    int lowerBound = (maxNumOfPixels == - 1 ) ? 1 : ( int ) Math. ceil ( Math
            . sqrt (w * h / maxNumOfPixels ) ) ;
    int upperBound = (minSideLength == - 1 ) ? 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 == - 1 ) && (minSideLength == - 1 ) ) {
        return 1 ;
    } else if (minSideLength == - 1 ) {
        return lowerBound ;
    } else {
        return upperBound ;
    }
}

你可能感兴趣的:(Android使用BitmapFactory.Options解决加载大图片内存溢出问题)