一, 位图重新采样
1, 有效的处理较大的位图
图像有各种不同的形状和大小。在很多情况下,他们往往比一个典型应用程序的用户界面(UI)所需要的资源更大。
读取一个位图的尺寸和类型:
为了从多种资源来创建一个位图,BitmapFactory类提供了几个解码的方法(decodeByteArray(), decodeFile(), decodeResource(), 等等) 。根据你的图像数据资源选择最合适的解码方法。这些方法试图请求分配内存来构造位图,因此很容易导致OutOfMemory异常。每种类型的解码方法都有额外的特征可以让你通过BitMapFactory.Options类指定解码选项。当解码时避免内存分配可以设置inJustDecodeBounds属性为true, 位图对象返回null但是设置了outWidth, outHeight和outMimeType。这种技术允许你在创建位图(和分配内存) 之前去读取图像的尺寸和类型。
示例:加载一个缩小版本到内存中:
2, 缓存位图
注: 我们可以引用第三方的包, xUtils来实现上述功能
http://blog.csdn.net/u013144863/article/details/51476503
public class MainActivity extends AppCompatActivity {
private ImageView imageView;
private LruCache<String, Bitmap> lruCache;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.imageView);
//获取当前activity内存大小, 谷歌默认为16M
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
int memoryClass = am.getMemoryClass();
final int cacheSize = memoryClass / 8 * 1024 * 1024;//单位为字节 (1/8的内存作为缓存大小, 通常)
lruCache = new LruCache<>(cacheSize);
}
//往缓存中存
public void addBitmapToCache(String key, Bitmap bitmap) {
if (getBitmapFromCache(key) == null) {
lruCache.put(key, bitmap);
}
}
//从缓存中读取方法
public Bitmap getBitmapFromCache(String key) {
return lruCache.get(key);
}
/**
* 位图重新采样
*
* @param res
* @param resId
* @param reqWidth
* @param reqHeight
* @return
*/
public Bitmap decodeSamleBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
public void showPicture(View view) {
String key = String.valueOf(R.drawable.img23);
//第一次执行时位图放入缓存中, 以后再执行时就不用再从网上或者本地获取了!
Bitmap bitmap = getBitmapFromCache(key);
if (bitmap == null) {
bitmap = decodeSamleBitmapFromResource(getResources(), R.drawable.img23, 50, 50);
addBitmapToCache(key, bitmap);
} else {
System.out.println("lruCache 中有位图");
}
imageView.setImageBitmap(bitmap);
}
/**
* 计算位图的采样比例
*
* @param options
* @param reqWidth
* @param reqHeight
* @return
*/
public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
//获取位位图的原宽高
int w = options.outWidth;
int h = options.outHeight;
//假设先让其为1
int inSampSize = 1;
//原来的图片比你想要的图片大
if (w > reqWidth || h > reqHeight) {
if (w > h) {
inSampSize = Math.round((float) h / (float) reqHeight);
} else {
inSampSize = Math.round((float) w / (float) reqWidth);
}
}
return inSampSize;
}
}