《Android开发艺术探索》笔记之Bitmap的高效加载

在 Android 中, BitmapFactory 类提供了四种加载 Bitmap 的方法:

  1. decodeFile, 从文件系统加载 Bitmap 对象;
  2. decodeResource, 从资源文件加载;
  3. decodeByteArray, 从字节数组中加载;
  4. decodeStream, 从输入流中加载, 此方法被 decodeFile 和 decodeResource 间接调用。

 

高效加载 Bitmap 的方法: 通过 BitmapFactory.Options 中的参数 inSampleSize (即采样率)来缩放图片。

过程如下:

  1. 将 BitmapFactory.Options 的 inJustDecodeBounds 参数设置为 true 并 “加载” 图片。 (当 inJustDecodeBounds 参数为 true 时, BitmapFactory 只会解析图片的原始宽高等信息, 并不会真正地加载图片);
  2. 从 BitmapFactory.Options 中取出图片原始宽高(即 outWidth 和 outHeight ), 结合目标 View 实际大小计算采样率 inSampleSize ;
  3. 将 BitmapFactory.Options 的 inJustDecodeBounds 参数设置为 false 并重新加载图片。

代码如下:

 1 public Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
 2         // First decode with inJustDecodeBounds=true to check dimensions
 3         final BitmapFactory.Options options = new BitmapFactory.Options();
 4         options.inJustDecodeBounds = true;
 5         BitmapFactory.decodeResource(res, resId, options);
 6 
 7         // Calculate inSampleSize
 8         options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
10 
11         // Decode bitmap with inSampleSize set
12         options.inJustDecodeBounds = false;
13         return BitmapFactory.decodeResource(res, resId, options);
14 }
 1 public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
 2         if (reqWidth == 0 || reqHeight == 0) {
 3             return 1;
 4         }
 5 
 6         // Raw height and width of image
 7         final int height = options.outHeight;
 8         final int width = options.outWidth;
 9         Log.d(TAG, "origin, w= " + width + " h=" + height);
10         int inSampleSize = 1;
11 
12         if (height > reqHeight || width > reqWidth) {
13             final int halfHeight = height / 2;
14             final int halfWidth = width / 2;
15 
16             // Calculate the largest inSampleSize value that is a power of 2 and
17             // keeps both
18             // height and width larger than the requested height and width.
19             while ((halfHeight / inSampleSize) >= reqHeight
20                     && (halfWidth / inSampleSize) >= reqWidth) {
21                 inSampleSize *= 2;
22             }
23         }
24 
25         Log.d(TAG, "sampleSize:" + inSampleSize);
26         return inSampleSize;
27 }

 

posted @ 2017-03-19 19:32  MayRain  阅读(280)  评论(0)    收藏  举报