关于Bitmap位图压缩图片的三种方式

2016-08-27 23:45 阅读 6,658 次 评论 0 条

摘要

对图片进行压缩,为了防止OutOfMemory(OOM),出现OOM的其中一种情况是对图片进行质量压缩时,调用的是Bitmap的compress(Bitmap.CompressFormat format, int quality, OutputStream stream),传递三个参数,format指定Bitmap压缩的格式:PNG,JPEG,WEBP,例如:Bitmap.CompressFormat.JPEG;第二个参数,quality指定压缩的质量,质量参数取值0——100,越接近0,压缩越厉害,像素减少,失真严重;第三个参数字节输出流对象,通常使用ByteArrayOutputStream字节数组输出流,缓冲字节数组,最后将字节数组缓冲流中的字节数重新生成转换成Bitmap对象,即压缩后的对象,例如:

  1. ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  2.     image.compress(Bitmap.CompressFormat.JPEG, 100, baos);  
  3.     while (baos.toByteArray().length / 1024 > 1024) {// 判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出  
  4.         baos.reset();// 重置baos即清空baos  
  5.         image.compress(Bitmap.CompressFormat.JPEG, 50, baos);// 这里压缩50%,把压缩后的数据存放到baos中  
  6.     }  
  7.     ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());  
  8.     BitmapFactory.Options newOpts = new BitmapFactory.Options();  
  9.     // 开始读入图片,此时把options.inJustDecodeBounds 设回true了  
  10.     newOpts.inJustDecodeBounds = true;  
  11.     Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);  

一.Bitmap类使用总结

Bitmap位于android.graphics包下,从上面压缩的例子中可以看出,Bitmap俗称位图,将图片转换成Bitmap对象,可以获取图片的高度/宽度/密度/字节数等信息,同理也可以设置图片的高度/宽度/密度/字节数等,这就稍微说明了Bitmap类适合处理图片压缩。下面继续看如何对图片进行比例压缩,压缩图片的比例为:480x800

  1. /**按照缩放比压缩图片 
  2.  * @param image 
  3.  * @return 
  4.  */  
  5. public static Bitmap comp(Bitmap image) {  
  6.     ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  7.     image.compress(Bitmap.CompressFormat.JPEG, 1024, baos);  
  8.     while (baos.toByteArray().length / 1024 > 100) {// 判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出  
  9.         baos.reset();// 重置baos即清空baos  
  10.         image.compress(Bitmap.CompressFormat.JPEG, 50, baos);// 这里压缩50%,把压缩后的数据存放到baos中  
  11.     }  
  12.     ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());  
  13.     BitmapFactory.Options newOpts = new BitmapFactory.Options();  
  14.     // 开始读入图片,此时把options.inJustDecodeBounds 设回true了  
  15.     newOpts.inJustDecodeBounds = true;  
  16.     Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);  
  17.     newOpts.inJustDecodeBounds = false;  
  18.     int w = newOpts.outWidth;  
  19.     int h = newOpts.outHeight;  
  20.     // 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为  
  21.     float hh = 800f;// 这里设置高度为800f  
  22.     float ww = 480f;// 这里设置宽度为480f  
  23.     // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可  
  24.     int be = 1;// be=1表示不缩放  
  25.     if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放  
  26.         be = (int) (newOpts.outWidth / ww);  
  27.     } else if (w < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放  
  28.         be = (int) (newOpts.outHeight / hh);  
  29.     }  
  30.     if (be <= 0)  
  31.         be = 1;  
  32.     newOpts.inSampleSize = be;// 设置缩放比例  
  33.     // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了  
  34.     isBm = new ByteArrayInputStream(baos.toByteArray());  
  35.     bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);  
  36. /       Bitmap b=compressImage(bitmap);// 压缩好比例大小后再进行质量压缩;  
  37.     return bitmap;  
  38. }  

压缩图片,除了压缩图片的质量,压缩的比例,还可以压缩图片的大小,上述代码while循环对图片的大小进行压缩,最终图片字节数小于等于100kb,防止图片OOM Exception。

你可能感兴趣的文章

来源:TeachCourse每周一次,深入学习Android教程,关注(QQ158#9359$239或公众号TeachCourse)
转载请注明出处: https://www.teachcourse.cn/2018.html ,谢谢支持!

资源分享

分类:Android 标签:,
Android事件分发流程分析证明(2) Android事件分发流程分析证明(
配置Linux主机防盗链 配置Linux主机防盗链
Android学习笔记十二:Android基础知识 Android学习笔记十二:Android
Eclipse+ADT Android快捷键大全 Eclipse+ADT Android快捷键