Android图片压缩几种方式总结

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();
    }
  }
}

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

(0)

相关推荐

  • Android WebP 图片压缩与传输

    1. 简介 直到4g时代,流量依然是宝贵的东西.而移动网络传输中,最占流量的一种载体:图片,成为了我们移动开发者不得不关注的一个问题. 我们关注的问题,无非是图片体积和质量如何达到一个比较和谐的平衡,希望得到质量不错的图片同时体积还不能太大. 走在时代前列的谷歌给出了一个不错的答案--WebP. WebP是一种图片文件格式,在相同的压缩指标下,webp的有损压缩能比jpg小 25-34%.而在我自己的测试里,有时候能小50%. 2. 大企业背书 WebP在2010年发布第一个版本,到现在已经6年

  • Android实现图片压缩(bitmap的六种压缩方式)

    Android中图片是以bitmap形式存在的,那么bitmap所占内存,直接影响到了应用所占内存大小,首先要知道bitmap所占内存大小计算方式: 图片长度 x 图片宽度 x 一个像素点占用的字节数 以下是图片的压缩格式: 其中,A代表透明度:R代表红色:G代表绿色:B代表蓝色. 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个

  • android bitmap compress(图片压缩)代码

    android的照相功能随着手机硬件的发展,变得越来越强大,能够找出很高分辨率的图片.有些场景中,需要照相并且上传到服务,但是由于图片的大小太大,那么就上传就会很慢(在有些网络情况下),而且很耗流量,要想速度快,那么就需要减小图片的大小.减少图片的大小有两种方法,1. 照小图片: 2. 压缩大图片. 照相时获取小图片一般不太符合要求,因为,图片的清晰度会很差,但是这种情况有个好处就是应用速度会快些: 压缩图片,就是把大图片压缩小,降低图片的质量,在一定范围内,降低图片的大小,并且满足需求(图片仍

  • Android图片压缩(质量压缩和尺寸压缩)

    在网上调查了图片压缩的方法并实装后,大致上可以认为有两类压缩:质量压缩(不改变图片的尺寸)和尺寸压缩(相当于是像素上的压缩):质量压缩一般可用于上传大图前的处理,这样就可以节省一定的流量,毕竟现在的手机拍照都能达到3M左右了,尺寸压缩一般可用于生成缩略图. 两种方法都实装在了我的项目中,结果却发现在质量压缩的模块中,本来1.9M的图片压缩后反而变成3M多了,很是奇怪,再做了进一步调查终于知道原因了.下面这个博客说的比较清晰: android图片压缩总结 总 结来看,图片有三种存在形式:硬盘上时是

  • android图片压缩的3种方法实例

    android 图片压缩方法: 第一:质量压缩法: 复制代码 代码如下: private Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArrayOutputStream();        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中        int op

  • Android实现图片压缩示例代码

    核心思想是通过BitmapFactory.Options来缩放图片,主要是用到了它的inSampleSize参数(采样率) 当inSampleSize为1的时候,采样后的图片大小为图片的原始大小: 当inSampleSize为2的时候,采样后的图片的宽和高是原来的1/2,也就是说,它的像素点是原来的1/4,占的内存自然就是原来的1/4了.以此类推. 当inSampleSize小于1的时候,效果和等于1的时候是一样的. 压缩流程如下: 1.BitmapFactory.Options 的inJust

  • Android图片压缩上传之基础篇

    在android程序开发中我们经常见到需要上传图片的场景,在这里有个技术点,需要把图片压缩处理,然后再进行上传.这样可以减少流量的消耗,提高图片的上传速度等问题. 关于android如何压缩,网上的资料也是很多,但大多数都是代码片段,讲解压缩步骤,而没有一个实用的工具类库.那么如何将压缩算法封装成一个实用工具库呢?其中会遇到些什么问题,比如: 1.需要压缩的图片有多少 2.压缩后的图片是覆盖还是保存到另外的目录 3.如果是另存目录需要将原始图片删除吗 4.如果改变压缩后的图片的尺寸大小是按照原图

  • Android中3种图片压缩处理方法

    Android中图片的存在形式: 1:文件形式:二进制形式存在与硬盘中. 2:流的形式:二进制形式存在与内存中. 3:Bitmap的形式 三种形式的区别: 文件形式和流的形式:对图片体积大小并没有影响.也就是说,如果你手机SD卡上的图片通过流的形式读到内存中,在内存中的大小也是原图的大小. 注意:不是Bitmap的形式. Bitmap的形式:图片占用的内存会瞬间变大. 以下是代码的形式: /** * 图片压缩的方法总结 */ /* * 图片压缩的方法01:质量压缩方法 */ private Bi

  • Android实现简单图片压缩的方法

    本文实例讲述了Android实现简单图片压缩的方法.分享给大家供大家参考,具体如下: 在开发图片浏览器等软件是,很多时候要显示图片的缩略图,而一般情况下,我们要将图片按照固定大小取缩略图,一般取缩略图的方法是使用BitmapFactory的decodeFile方法,然后通过传递进去 BitmapFactory.Option类型的参数进行取缩略图,在Option中,属性值inSampleSize表示缩略图大小为原始图片大小的几分之一,即如果这个值为2,则取出的缩略图的宽和高都是原始图片的1/2,图

  • 详解Android 图片的三级缓存及图片压缩

    为什么需要图片缓存 Android默认给每个应用只分配16M的内存,所以如果加载过多的图片,为了防止内存溢出,应该将图片缓存起来.图片的三级缓存分别是: 内存缓存 本地缓存 网络缓存 其中,内存缓存应优先加载,它速度最快:本地缓存次优先加载,它速度也快:网络缓存不应该优先加载,它走网络,速度慢且耗流量. 三级缓存的具体实现 网络缓存 根据图片的url去加载图片 在本地和内存中缓存 public class NetCacheUtils { private LocalCacheUtils mLoca

随机推荐