Android图片压缩几种方式总结

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

Android图片压缩几种方式总结

图片压缩在Android开发中很常见也很重要,防止图片的OOM也是压缩的重要原因。

首先看下Bitmap图片文件的大小的决定因素:

Bitmap所占用的内存 = 图片长度 x 图片宽度 x 一个像素点占用的字节数。3个参数,任意减少一个的值,就达到了压缩的效果。

接下来看下Bitmap图片的几种格式的特点:

ALPHA_8
 表示8位Alpha位图,即A=8,一个像素点占用1个字节,它没有颜色,只有透明度
 ARGB_4444
表示16位ARGB位图,即A=4,R=4,G=4,B=4,一个像素点占4+4+4+4=16位,2个字节
ARGB_8888
表示32位ARGB位图,即A=8,R=8,G=8,B=8,一个像素点占8+8+8+8=32位,4个字节
RGB_565
表示16位RGB位图,即R=5,G=6,B=5,它没有透明度,一个像素点占5+6+5=16位,2个字节

如果进行图片格式的压缩的话,一般情况下都是ARGB_8888转为RGB565进行压缩。

写了一个工具类,基本上列举了android上图片的几种基本压缩方式:

1.质量压缩

2.采样率压缩

3.尺寸压缩

4.Matrix压缩

5.图片格式的压缩,例如PNG和JPG保存后的图片大小是不同的

public class Utils { 
 
  /** 
   * 采样率压缩 
   * 
   * @param bitmap 
   * @param sampleSize 采样率为2的整数倍,非整数倍四舍五入,如4的话,就是原图的1/4 
   * @return 尺寸变化 
   */ 
  public static Bitmap getBitmap(Bitmap bitmap, int sampleSize) { 
    BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inSampleSize = sampleSize; 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); 
    byte[] bytes = baos.toByteArray(); 
    Bitmap bit = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options); 
    Log.i("info", "图片大小:" + bit.getByteCount());//2665296  10661184 
    return bit; 
  } 
 
  /** 
   * 图片质量压缩 
   * 
   * @param bitmap 
   * @param quality 
   * @return 尺寸不变,质量变小 
   */ 
  public static Bitmap compressByQuality(Bitmap bitmap, int quality) { 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos); 
    byte[] bytes = baos.toByteArray(); 
    Bitmap bit = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); 
    Log.i("info", "图片大小:" + bit.getByteCount());//10661184 
    return bit; 
  } 
 
  /** 
   * 图片质量压缩 
   * 
   * @param src 
   * @param maxByteSize 
   * @return 
   */ 
  public static Bitmap compressByQuality(Bitmap src, long maxByteSize) { 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    int quality = 100; 
    src.compress(Bitmap.CompressFormat.JPEG, quality, baos); 
    while (baos.toByteArray().length > maxByteSize && quality > 0) { 
      baos.reset(); 
      src.compress(Bitmap.CompressFormat.JPEG, quality -= 5, baos); 
    } 
    if (quality < 0) return null; 
    byte[] bytes = baos.toByteArray(); 
    Bitmap bit = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); 
    return bit; 
  } 
 
  public static Bitmap compressByFormat(Bitmap bitmap, int format) { 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); 
    byte[] bytes = baos.toByteArray(); 
    Bitmap bit = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); 
    Log.i("info", "图片大小:" + bit.getByteCount());//10661184 
    return bit; 
  } 
 
  /** 
   * Matrix缩放 
   * 
   * @param bitmap 
   * @param scaleWidth 
   * @param scaleHeight 
   * @return 尺寸和大小变化 
   */ 
  public static Bitmap getBitmapBySize(Bitmap bitmap, float scaleWidth, float scaleHeight) { 
    Matrix matrix = new Matrix(); 
    matrix.postScale(scaleWidth, scaleHeight); 
    Bitmap bit = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false); 
    Log.i("info", "图片大小:" + bit.getByteCount()); 
    return bit; 
  } 
 
  /** 
   * 按照图片格式配置压缩 
   * 
   * @param path 
   * @param config ALPHA_8,ARGB_4444,ARGB_8888,RGB_565; 
   * @return RGB_565比ARGB_8888节省一半内存 
   */ 
  public static Bitmap getBitmapByFormatConfig(String path, Bitmap.Config config) { 
    BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inPreferredConfig = config; 
    Bitmap bitmap = BitmapFactory.decodeFile(path, options); 
    Log.i("info", "图片大小:" + bitmap.getByteCount()); 
    return bitmap; 
  } 
 
  /** 
   * 指定大小缩放 
   * 
   * @param bitmap 
   * @param width 
   * @param height 
   * @return 
   */ 
  public static Bitmap getBitmapByScaleSize(Bitmap bitmap, int width, int height) { 
    Bitmap bit = Bitmap.createScaledBitmap(bitmap, width, height, true); 
    Log.i("info", "图片大小:" + bit.getByteCount()); 
    return bit; 
  } 
 
  /** 
   * 通过保存格式压缩 
   * 
   * @param bitmap 
   * @param format JPEG,PNG,WEBP 
   * @return 
   */ 
  public static Bitmap getBitmapByFormat(Bitmap bitmap, Bitmap.CompressFormat format) { 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    bitmap.compress(format, 100, baos); 
    byte[] bytes = baos.toByteArray(); 
    Bitmap bit = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); 
    Log.i("info", "图片大小:" + bit.getByteCount()); 
    return bit; 
  } 
 
  /** 
   * 文件加载压缩 
   * 
   * @param filePath 
   * @param inSampleSize 
   * @return 
   */ 
  public static Bitmap getBitmap(String filePath, int inSampleSize) { 
    BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeFile(filePath, options);//此时不耗费和占用内存 
    options.inSampleSize = inSampleSize; 
    options.inJustDecodeBounds = false; 
    return BitmapFactory.decodeFile(filePath, options); 
  } 
 
  public static Bitmap getBitmap(String filePath) { 
    return BitmapFactory.decodeFile(filePath); 
  } 
 
  public static Bitmap view2Bitmap(View view) { 
    if (view == null) return null; 
    Bitmap ret = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888); 
    Canvas canvas = new Canvas(ret); 
    Drawable bgDrawable = view.getBackground(); 
    if (bgDrawable != null) { 
      bgDrawable.draw(canvas); 
    } else { 
      canvas.drawColor(Color.WHITE); 
    } 
    view.draw(canvas); 
    return ret; 
  } 
 
  public static void saveBitmap(Bitmap bitmap) { 
    File file = new File(Environment.getExternalStorageDirectory() + "/img.jpg"); 
    try { 
      FileOutputStream fileOutputStream = new FileOutputStream(file); 
      bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream); 
      fileOutputStream.flush(); 
      fileOutputStream.close(); 
    } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
    } catch (IOException e) { 
      e.printStackTrace(); 
    } 
  } 
 
  public static void saveBitmap(Bitmap bitmap,Bitmap.CompressFormat format) { 
    File file = new File(Environment.getExternalStorageDirectory() + "/img.jpg"); 
    try { 
      FileOutputStream fileOutputStream = new FileOutputStream(file); 
      bitmap.compress(format, 100, fileOutputStream); 
      fileOutputStream.flush(); 
      fileOutputStream.close(); 
    } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
    } catch (IOException e) { 
      e.printStackTrace(); 
    } 
  } 
} 

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

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

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 分享
查看更多