Android Bitmap二次采样,大图处理

Bitmap 二次采样:
二次采样的目的是将高分辨率的图片进行采样缩放(个人理解,二次采样,应该是指二次调用了编码图片。但是两次编码所做的事情都是不一样的)。由于手机给每个APP分配的空间是有限的。所以若是不对图片进行缩放的话,就容易造成内存溢出(即OOM,out of memory)。
*官方文档推荐使用Glide来加载图片。
1.第一次采样:
第一次是获取图片的边框的长度与高度,BitmapFactory编码图片的方法有很多:

decodeByteArray(), decodeFile(), decodeResource()等。
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; //从英文就可理解,是否只是编码边框
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
/*得出图片的真实高度和宽度的时候,我们需要将其与我们需要的高度和宽度进行一个比值,从而得出我们需要的缩放的比例*/

这里先解释下这个参数,文档中解释的大致意思是,若inSampleSize==4,那么原图的缩放就是1/4,像素比是1/16。并且若是inSampleSize<=1,都将设置为1。而且inSampleSize必须是2的幂次方,否则都会将inSampleSize舍入到最接近2的幂次方的数值。
inSampleSize

/** 该方法即是计算图片缩放比例
  * options 原图的参数
  */
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) >= reqHeight
                && (halfWidth / inSampleSize) >= reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}

2.第二次采样:
第二次采样就是按照计算出来的压缩比率来进行图片的编码。

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    options.inJustDecodeBounds = false;
    // 配置好计算的到的inSampleSize,将inJustDecodeBounds设置为false,那么即是将图片进行编码以的到我们需要的压缩的图片
    return BitmapFactory.decodeResource(res, resId, options);
}

Bitmap的像素格式:
ALPHA_8 只有一个alpha通道
ARGB_4444 这个从API 13开始不建议使用,因为质量太差
ARGB_8888 ARGB四个通道,每个通道8bit
RGB_565 每个像素占2Byte,其中红色占5bit,绿色占6bit,蓝色占5bit

参考文档:
https://developer.android.com/topic/performance/graphics/load-bitmap.html#load-bitmap
https://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize
https://developer.android.com/reference/android/graphics/Bitmap.Config.html
bitmap 内存管理,尚未学习与了解
https://developer.android.com/topic/performance/graphics/manage-memory.html
http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=498

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值