在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();
```