Android图片压缩的实例详解

所属分类: 软件编程 / Android 阅读数: 40
收藏 0 赞 0 分享

Android图片压缩的实例详解

在做微信分享的时候,由于分享的缩略图要求不得大于32K,否则不能调起微信,所以总结了一下Android图片的压缩问题,大部分资料都是来自网上各位的分享,自己只是完善或修改了一下,本着继续分享的精神,也方便自己记忆,于是总结如下。

android图片压缩主要有两种方式:1.压缩图片分辨率 2.压缩图片质量

一、先看压缩图片分辨率,很好理解,如本来1280*768的图片压缩为640*384大小。废话不说,直接上代码:



/** 
   * 按比例压缩图片分辨率 
   * @param inBitmap 
   * @param outHeight 输出图片高度,可据此保持比例计算输出宽度 
   * @param needRecycled 是否回收inBitmap 
   * @return 
   */ 
  public static Bitmap createScaledBitmapByOutHeight(Bitmap inBitmap, int outHeight, boolean needRecycled) {      
    int bitmapHeight = inBitmap.getHeight(); 
    int bitmapWidth = inBitmap.getWidth(); 
    int outWidth = bitmapWidth * outHeight / bitmapHeight; 
     
    return createScaledBitmap(inBitmap, outWidth, outHeight, needRecycled); 
  }  
   
  /** 
   * 按比例压缩图片分辨率 
   * @param inBitmap 
   * @param outHeight 输出图片宽度,可据此保持比例计算输出高度 
   * @param needRecycled 是否回收inBitmap 
   * @return 
   */ 
  public static Bitmap createScaledBitmapByOutWidth(Bitmap inBitmap, int outWidth, boolean needRecycled) {     
    int bitmapHeight = inBitmap.getHeight(); 
    int bitmapWidth = inBitmap.getWidth(); 
    int outHeight = bitmapHeight * outWidth / bitmapWidth; 
     
    return createScaledBitmap(inBitmap, outWidth, outHeight, needRecycled); 
  } 
   
  /** 
   * 指定输出的宽高缩放图片 
   * @param inBitmap 
   * @param outWidth 
   * @param outHeight 
   * @param needRecycled 
   * @return 
   */ 
  public static Bitmap createScaledBitmap(Bitmap inBitmap, int outWidth, int outHeight, boolean needRecycled) {         
     
    Bitmap thumbBmp = Bitmap.createScaledBitmap(inBitmap, outWidth, outHeight, true); 
    if (needRecycled) { 
      inBitmap.recycle(); 
    } 
     
    return thumbBmp; 
  } 

前两个方法可以指定期望的宽度或高度,并按比例缩放图片的分辨率,第3个方法可以随意指定期望的宽高,缩放图片。

上面代码是对输入的bitmap进行缩放,还可以从资源或文件中加载图片并缩放,具体如下:

/** 
   * 从资源加载并压缩图片 
   * @param res 
   * @param resId 
   * @param outWidth 目标宽度 
   * @param outHeight 目标高度 
   * @return 
   */ 
  public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,  
      int outWidth, int outHeight) {  
    final BitmapFactory.Options options = new BitmapFactory.Options();  
    options.inJustDecodeBounds = true; // 假解,来获取图片大小  
    BitmapFactory.decodeResource(res, resId, options);  
    options.inSampleSize = calculateInSampleSize(options, outWidth, outHeight);  
    // 使用获取到的inSampleSize值再次解析图片  
    options.inJustDecodeBounds = false; 
    //options.inPreferredConfig = Config.RGB_565; 
    return BitmapFactory.decodeResource(res, resId, options);  
  }  
   
  /** 
   * 从文件中加载并压缩图片 
   * @param res 
   * @param resId 
   * @param outWidth 目标宽度 
   * @param outHeight 目标高度 
   * @return 
   */ 
  public static Bitmap decodeSampledBitmapFromFile(String pathName, int outWidth, int outHeight) { 
    final BitmapFactory.Options options = new BitmapFactory.Options();  
    options.inJustDecodeBounds = true; // 假解,来获取图片大小  
    BitmapFactory.decodeFile(pathName, options); 
    options.inSampleSize = calculateInSampleSize(options, outWidth, outHeight);  
    // 使用获取到的inSampleSize值再次解析图片  
    options.inJustDecodeBounds = false; 
    //options.inPreferredConfig = Config.RGB_565; 
    return BitmapFactory.decodeFile(pathName, options); 
  }  
   
  /** 
   * 计算options.inSampleSize 
   * @param options 
   * @param reqWidth 
   * @param reqHeight 
   * @return 
   */ 
  public static int calculateInSampleSize(BitmapFactory.Options options,  
      int reqWidth, int reqHeight) {  
    // 源图片的高度和宽度  
    final int height = options.outHeight;  
    final int width = options.outWidth;  
    int inSampleSize = 1;  
    if (height > reqHeight || width > reqWidth) {  
      // 计算出实际宽高和目标宽高的比率  
      final int heightRatio = Math.round((float) height / (float) reqHeight);  
      final int widthRatio = Math.round((float) width / (float) reqWidth);  
      // 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高  
      // 一定都会大于等于目标的宽和高。  
      inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;  
    }  
    return inSampleSize;  
  }  

二、压缩图片的质量

/** 
   * 压缩图片质量,把图片压缩到outSize以内 
   * @param inBitmap 原始bitmap 
   * @param outSize 压缩到的大小 
   * @param needRecycled 是否回收bitmap 
   * @return 
   */ 
  public static Bitmap compressImage(Bitmap inBitmap, int outSize, boolean needRecycled) {  
      
    ByteArrayOutputStream baos = new ByteArrayOutputStream();  
    inBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); 
    int quality = 100;  
    while (baos.toByteArray().length / 1024 > outSize) { 
      if (quality <= 0) { 
        ByteArrayInputStream outBais = new ByteArrayInputStream(baos.toByteArray()); 
        return BitmapFactory.decodeStream(outBais, null, null);// 如果quaLity为0时还未达到32k以内,返回得到的最小值;如需要可结合分辨率压缩 
      } 
      baos.reset(); 
      //PNG格式下,这种压缩不起作用(quality:0-100,如果目标大小太小,有时候质量压缩不一定能达到效果,需结合分辨率压缩) 
      inBitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos); 
      Log.e("AN", "bitmap size:"+ baos.toByteArray().length / 1024 + "k"); 
      quality -= 10; 
    } 
    if (needRecycled) { 
      inBitmap.recycle(); 
    } 
     
     
    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 
    Bitmap outBitmap= BitmapFactory.decodeStream(bais, null, null);//ByteArrayInputStream转成bitmap 
     
    return outBitmap;  
  } 


需要注意的是compress方法,该压缩方法只对JPEG格式有效,对于PNG格式,则会忽略第二个参数quality,即压缩不起作用。这种压缩只是对图片质量有影响,并不会改变图片大小。

当然,如有需要,以上两种压缩方法可以结合使用。

以上就是Android 图片压缩的实现方法的详解,如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

更多精彩内容其他人还在看

Android网络编程之获取网络上的Json数据实例

这篇文章主要介绍了Android网络编程之获取网络上的Json数据实例,本文用完整的代码实例讲解了在Android中读取网络中Json数据的方法,需要的朋友可以参考下
收藏 0 赞 0 分享

Android中的windowSoftInputMode属性详解

这篇文章主要介绍了Android中的windowSoftInputMode属性详解,本文对windowSoftInputMode的9个属性做了详细总结,需要的朋友可以参考下
收藏 0 赞 0 分享

Android网络编程之UDP通信模型实例

这篇文章主要介绍了Android网络编程之UDP通信模型实例,本文给出了服务端代码和客户端代码,需要的朋友可以参考下
收藏 0 赞 0 分享

Android中使用ListView实现漂亮的表格效果

这篇文章主要介绍了Android中使用ListView实现漂亮的表格效果,本文用详细的代码实例创建了一个股票行情表格,需要的朋友可以参考下
收藏 0 赞 0 分享

Android中刷新界面的二种方法

这篇文章主要介绍了Android中刷新界面的二种方法,本文使用Handler、postInvalidate两种方法实现界面刷新,需要的朋友可以参考下
收藏 0 赞 0 分享

Android SDK三种更新失败及其解决方法

这篇文章主要介绍了Android SDK三种更新失败及其解决方法,需要的朋友可以参考下
收藏 0 赞 0 分享

Android学习笔记——Menu介绍(一)

Android3.0(API level 11)开始,Android设备不再需要专门的菜单键。随着这种变化,Android app应该取消对传统6项菜单的依赖。取而代之的是提供anction bar来提供基本的用户功能
收藏 0 赞 0 分享

Android学习笔记——Menu介绍(二)

这次将继续上一篇文章没有讲完的Menu的学习,上下文菜单(Context menu)和弹出菜单(Popup menu)
收藏 0 赞 0 分享

Android学习笔记——Menu介绍(三)

今天继续昨天没有讲完的Menu的学习,主要是Popup Menu的学习,需要的朋友可以参考下
收藏 0 赞 0 分享

Android显示网络图片实例

这篇文章主要介绍了Android显示网络图片的方法,以实例形式展示了Android程序显示网络图片的方法,非常具有实用价值,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多