在Android中对图片操作一般都会用到Bitmap类,使用的时候出现的一些常见问题:
内存泄漏 或 OOM(主要问题)
图片格式设置问题:ALPHA_8、ARGB_4444、ARGB_8888、RGB_565
Bitmap的获取问题
…
1、内存泄漏 或 OOM
Android中图片占用内存的计算方式:图片的尺寸(长宽)一个像素占的内存大小
其中一个像素占的内存大小按不同图片格式区分:
- ALPHA_8 (每个像素占1字节)
- ARGB_4444(每个像素占2字节)
- ARGB_8888(每个像素占4字节)
RGB_565(每个像素占2字节)
根据以上的图片计算方式,Android给每个application分配的内存有限制,如果使用内存大小超过限制,就会造成OOM。
如果一个图片的长宽非常大,如1920*1080,按上面计算方式,内存就会超出限制。
因此,要对图片进行压缩。1.1图片压缩
图片压缩有几种形式;有尺寸缩放压缩,质量压缩,采样率压缩,将图片格式设置成低内存的格式如RGB565
缩放压缩
质量压缩
/** * 质量压缩:在内存中的大小不变 * * @param image * @return */ private static Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); int quality = 50; image.compress(Bitmap.CompressFormat.JPEG, quality, baos);//这里压缩quality%,把压缩后的数据存放到baos中 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中 Bitmap bitmap = BitmapFactory.decodeStream(bais, null, null);//把ByteArrayInputStream数据生成图片 return bitmap; }
采样率压缩
/** * 质量压缩,不改变内存大小 * @param context * @param imageId * @return */ public static Bitmap CompressByOption(Context context, int imageId) { BitmapFactory.Options options = new BitmapFactory.Options(); //采样率 options.inSampleSize = 2; //主要的是options参数,不同的decodeResource方法只要用上options Bitmap bm = BitmapFactory.decodeResource(context.getResources(), imageId, options); return bm; }
- 格式压缩
/**
<ul><li>格式压缩
*</li>
<li>@param context</li>
<li>@param imageId</li>
<li>@return
*/
public static Bitmap CompressByChangeType(Context context, int imageId) {
BitmapFactory.Options options = new BitmapFactory.Options();
//将图片格式改为RGB_565,占用内存相对较小
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap bm = BitmapFactory.decodeResource(context.getResources(), imageId, options);
return bm;
}
1.2 及时回收Bitmap
不再需要时调用bitmap.recycle(),就及时置空
```
/**
* Recycle the userless bitmap
*
* @param bitmap
*/
public static void recycleBitmap(Bitmap bitmap) {
if (bitmap != null) {
if (!bitmap.isRecycled()) {
bitmap.recycle();
}
bitmap = null;
}
System.gc();
}
```
1.3 运用软引用 SoftReference<>来进行数据的及时回收,或多图片加载时利用Lrucache进行缓存
```
SoftReference<Bitmap> bitmapSoftReference = new SoftReference<>(bitmap);
Bitmap softBitmap = bitmapSoftReference.get();
```