Bitmap的常见问题

在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();
```
…//TODO
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值