2
3 import java.io.FileDescriptor;
4 import java.io.FileInputStream;
5
6 import android.graphics.Bitmap;
7 import android.graphics.BitmapFactory;
8
9 /**
10 * 图片处理类 压缩
11 *
12 * @author Administrator
13 *
14 */
15 public class ImageUtil {
16 /**
17 * get Bitmap
18 *
19 * @param imgPath
20 * @param minSideLength
21 * @param maxNumOfPixels
22 * @return
23 */
24 public static Bitmap getBitmap(String imgPath, int minSideLength,
25 int maxNumOfPixels) {
26 if (imgPath == null || imgPath.length() == 0)
27 return null;
28
29 try {
30 FileDescriptor fd = new FileInputStream(imgPath).getFD();
31 BitmapFactory.Options options = new BitmapFactory.Options();
32 options.inJustDecodeBounds = true;
33 // BitmapFactory.decodeFile(imgFile, options);
34 BitmapFactory.decodeFileDescriptor(fd, null, options);
35
36 options.inSampleSize = computeSampleSize(options,
37 minSideLength, maxNumOfPixels);
38 try {
39 // 这里一定要将其设置回false,因为之前我们将其设置成了true
40 // 设置inJustDecodeBounds为true后,decodeFile并不分配空间,即,BitmapFactory解码出来的Bitmap为Null,但可计算出原始图片的长度和宽度
41 options.inJustDecodeBounds = false;
42
43 Bitmap bmp = BitmapFactory.decodeFile(imgPath, options);
44 return bmp == null ? null : bmp;
45 } catch (OutOfMemoryError err) {
46 return null;
47 }
48 } catch (Exception e) {
49 return null;
50 }
51 }
52
53 /**
54 * compute Sample Size
55 *
56 * @param options
57 * @param minSideLength
58 * @param maxNumOfPixels
59 * @return
60 */
61 private static int computeSampleSize(BitmapFactory.Options options,
62 int minSideLength, int maxNumOfPixels) {
63 int initialSize = computeInitialSampleSize(options, minSideLength,
64 maxNumOfPixels);
65
66 int roundedSize;
67 if (initialSize <= 8) {
68 roundedSize = 1;
69 while (roundedSize < initialSize) {
70 roundedSize <<= 1;
71 }
72 } else {
73 roundedSize = (initialSize + 7) / 8 * 8;
74 }
75
76 return roundedSize;
77 }
78
79 /**
80 * compute Initial Sample Size
81 *
82 * @param options
83 * @param minSideLength
84 * @param maxNumOfPixels
85 * @return
86 */
87 private static int computeInitialSampleSize(BitmapFactory.Options options,
88 int minSideLength, int maxNumOfPixels) {
89 double w = options.outWidth;
90 double h = options.outHeight;
91
92 // 上下限范围
93 int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math
94 .sqrt(w * h / maxNumOfPixels));
95 int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(
96 Math.floor(w / minSideLength), Math.floor(h / minSideLength));
97
98 if (upperBound < lowerBound) {
99 // return the larger one when there is no overlapping zone.
100 return lowerBound;
101 }
102
103 if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
104 return 1;
105 } else if (minSideLength == -1) {
106 return lowerBound;
107 } else {
108 return upperBound;
109 }
110 }
111 }