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图片质量压缩以及缩略图生成】本人Android菜鸟一枚,如有错误,欢迎指正,谢谢大家!

    推荐阅读