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 }