Android图片质量压缩以及缩略图生成

1、图片的质量压缩

图片的质量压缩是指,仅仅压缩图片文件的大小,但当图片加载到内存中时,占用的内存大小并没有太大变化。可以通过质量压缩,加快图片上传的速度。

代码如下:

/**
*将文件压缩后覆盖源文件
*/
public static void compressImage(File file) {
Bitmap bitmap=BitmapFactory.decodeFile(file.getAbsolutePath());
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 80, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
        int options = 80;//先压缩到80%
        while (baos.toByteArray().length / 1024 > 200) { // 循环判断如果压缩后图片是否大于200kb,大于继续压缩
            if (options <= 0) {//有的图片过大,可能当options小于或者等于0时,它的大小还是大于目标大小,于是就会发生异常,异常的原因是options超过规定值。所以此处需要判断一下
                break;
            }
            baos.reset();// 重置baos即清空baos
            options -= 10;// 每次都减少10
            bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);
        }
        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(baos.toByteArray());
            fos.close();
            baos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

通过上述代码,可以将2.5M的图片压缩到200KB左右,并且图片的清晰度差别不大,但是需要注意的是,这改变的只是图片文件的大小,并不能改变加载此图片的内存大小。所以对于此类图片,在加载的时候也是需要注意的,避免OOM异常。需要注意的是,上述代码执行时,还是需要时间的,所以最好放在子线程中执行。



2、缩略图生成

缩略图生成的图片会改变内存占用的大小,所以一般不需要显示全图情况,可以用缩略图去展示,减少程序内存损耗。

代码如下:

    /**
     * 获取缩略图
     * @param imagePath:文件路径
     * @param width:缩略图宽度
     * @param height:缩略图高度
     * @return
     */
    public static Bitmap getImageThumbnail(String imagePath, int width, int height) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true; //关于inJustDecodeBounds的作用将在下文叙述
        Bitmap bitmap = BitmapFactory.decodeFile(imagePath, options);
        int h = options.outHeight;//获取图片高度
        int w = options.outWidth;//获取图片宽度
        int scaleWidth = w / width; //计算宽度缩放比
        int scaleHeight = h / height; //计算高度缩放比
        int scale = 1;//初始缩放比
        if (scaleWidth < scaleHeight) {//选择合适的缩放比
            scale = scaleWidth;
        } else {
            scale = scaleHeight;
        }
        if (scale <= 0) {//判断缩放比是否符合条件
            be = 1;
        }
        options.inSampleSize = scale;
        // 重新读入图片,读取缩放后的bitmap,注意这次要把inJustDecodeBounds 设为 false
                options.inJustDecodeBounds = false;
                bitmap = BitmapFactory.decodeFile(imagePath, options);
        // 利用ThumbnailUtils来创建缩略图,这里要指定要缩放哪个Bitmap对象
        bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
        return bitmap;
    }

通过上述代码加载图片的缩略图,将会有效的避免OOM异常。在这里需要解释下options.inJustDecodeBounds这个属性,当options.inJustDecodeBounds设置为true时,通过BitmapFactory.decodeFile去加载图片,将不会正真地返回bitmap,也就是说此时的bitmap为null。它的作用是将图片的相关信息,例如图片宽高,大小等信息带到options中,方便我们后续计算图片的宽高比。

当我们计算好宽高比后,通过options.inSampleSize来设置缩放比例,然后将options.inJustDecodeBounds的值设置为false,再通过BitmapFactory.decodeFile去加载图片就能获取真正的bitmap对象了。最后通过ThumbnailUtils.extractThumbnail来获取最终的缩略图。需要说明的是,ThumbnailUtils.OPTIONS_RECYCLE_INPUT表示回收创建缩略图时的资源。

或许有的朋友觉得既然已经通过BitmapFactory.decodeFile的方式处理过了,为什么还需要ThumbnailUtils.extractThumbnail来再处理一次呢。首先,仅仅通过之前的处理,最终的缩略图的宽高还是和我们设置的大小有点出入的,所以用ThumbnailUtils再处理一次。可能又会有人说了,为什么不直接使用ThumbnailUtils来生成缩略图呢?因为使用ThumbnailUtils是需要传入bitmap的,试问有没有这样的情况,图片太大,导致在加载图片的时候直接就OOM了,那还怎么使用ThumbnailUtils呢?

本人Android菜鸟一枚,如有错误,欢迎指正,谢谢大家!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值