博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 的图片压缩
阅读量:4205 次
发布时间:2019-05-26

本文共 3190 字,大约阅读时间需要 10 分钟。

我用的图片主要分为3种       1、质量压缩 ,2、尺寸压缩,3、Luban压缩(鲁班)

一、质量压缩

   质量压缩的特点是:  File形式的图片确实被压缩了, 但是当你重新读取压缩后的file为 Bitmap是,它占用的内存并没有改变           

  质量压缩主要借助Bitmap中的compress方法实现:

public boolean compress (Bitmap.CompressFormat format, int quality, OutputStream stream)

 

这个方法用来将特定格式的压缩图片写入输出流(OutputStream)中,当然例如输出流与文件联系在一起,压缩后的图片也就是一个文件。如果压缩成功则返回true,其中有三个参数:

  • format是压缩后的图片的格式,可取值:Bitmap.CompressFormat .JPEG、~.PNG、~.WEBP。
  • quality的取值范围为[0,100],值越小,经过压缩后图片失真越严重,当然图片文件也会越小。(PNG格式的图片会忽略这个值的设定)
  • stream指定压缩的图片输出的地方,比如某文件。

下面是质量压缩的代码:

  1. public static void compressBmpToFile(Bitmap bmp,File file){  
  2.         ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  3.         int options = 80;//个人喜欢从80开始,  
  4.         bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);  
  5.         while (baos.toByteArray().length / 1024 > 100) {   
  6.             baos.reset();  
  7.             options -= 10;  
  8.             bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);  
  9.         }  
  10.         try {  
  11.             FileOutputStream fos = new FileOutputStream(file);  
  12.             fos.write(baos.toByteArray());  
  13.             fos.flush();  
  14.             fos.close();  
  15.         } catch (Exception e) {  
  16.             e.printStackTrace();  
  17.         }  
  18.     }  

二、尺寸压缩

特点: 通过设置采样率, 减少图片的像素, 达到对内存中的Bitmap进行压缩

我们主要通过BitmapFactory中的decodeFile方法对图片进行尺寸压缩:

public static Bitmap decodeFile (String pathName, BitmapFactory.Options opts)

 

其中有两个参数:

  • pathName是图片文件的路径。
  • opts 就是所谓的采样率,它里边有很多属性可以设置,我们通过设置属性来达到根据自己的需要,压缩出指定的图片。其中比较常用的属性有:

boolean inJustDecodeBounds —— 如果设置为true,则只读取bitmap的宽高,而忽略内容。

int inSampleSize—— 如果>1,调用decodeFile方法后,就会得到一个更小的bitmap对象(已压缩)。比如设置为2,那么新Bitmap的宽高都会是原Bitmap宽高的1/2,总体大小自然就是原来的1/4了,以此类推。

boolean inPurgeable—— 如果设置为true,压缩后的图片像素占的内存将会在系统清理内存的时候被回收掉,当像素的信息再次被用到时将会自动重新decode该像素(比如getPixels()时)。(慎用!重复decode可以会造成UI的卡顿,API level 21 已弃用)

boolean inInputShareable—— 与inPurgeable配合使用,如果inPurgeable设置成false,自动忽略此值,如果inPurgeable为true,此值决定是否该bitmap能分享引用给输入数据(inputstream,array等),或者必须进行深拷贝。API level 21 已弃用。(这是译文,不太理解!!!)

 

下面是一段实现的代码

 
  1. private Bitmap sizeCompres(String path, int rqsW, int rqsH) {

  2. // 用option设置返回的bitmap对象的一些属性参数

  3. final BitmapFactory.Options options = new BitmapFactory.Options();

  4. options.inJustDecodeBounds = true;// 设置仅读取Bitmap的宽高而不读取内容

  5. BitmapFactory.decodeFile(path, options);// 获取到图片的宽高,放在option里边

  6. final int height = options.outHeight;//图片的高度放在option里的outHeight属性中

  7. final int width = options.outWidth;

  8. int inSampleSize = 1;

  9. if (rqsW == 0 || rqsH == 0) {

  10. options.inSampleSize = 1;

  11. } else if (height > rqsH || width > rqsW) {

  12. final int heightRatio = Math.round((float) height / (float) rqsH);

  13. final int widthRatio = Math.round((float) width / (float) rqsW);

  14. inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;

  15. options.inSampleSize = inSampleSize;

  16. }

  17. return BitmapFactory.decodeFile(path, options);// 主要通过option里的inSampleSize对原图片进行按比例压缩

  18. }

三、Luban压缩

这里介绍下一个第三方开源库——

2.使用Luban压缩图片效果

  

上面两图中的上部分图片是原图,下面部分是经过Luban压缩过后的图片

效果:

第一张原图4.55m 尺寸3456x4608。 压缩过后53k 尺寸1152x1536

第二张原图1.16m 尺寸1080x1920。 压缩过后150k 尺寸360x640

我们可以发现压缩后的图片在不放大的情况下,图片效果和原图一致,Luban的处理效果特别好。

如何使用Luban压缩图片

1.在项目中的build.gradle添加依赖(需要用到RxJava1.0) 

这里写图片描述

2.在代码中使用Luban压缩方法

1)Listerner方式。传入图片File,调用设置压缩监听setCompressListerner方法,处理压缩结果。 

这里写图片描述

2)Rxjava方式,传入图片File,调用asObservable方法返回一个Observable观察者对象,使用RxJava方式来处理压缩结果。 

这里写图片描述

3.Luban源码分析

源码中最主要的方法就是thirdCompress(File file),即如何计算得出理想的压缩后宽高,以及图片大小。

Luban存在的不足

1.不能很好的支持多图片压缩。(出现问题:多图压缩出现OOM)

2.项目使用中必须添加RxJava依赖。(已在测试项目中剔除掉RxJava依赖 

 

 

 

你可能感兴趣的文章
【一天一道LeetCode】#48. Rotate Image
查看>>
【一天一道LeetCode】#56. Merge Intervals
查看>>
【一天一道LeetCode】#57. Insert Interval
查看>>
【一天一道LeetCode】#58. Length of Last Word
查看>>
【一天一道LeetCode】#59. Spiral Matrix II
查看>>
【一天一道LeetCode】#30. Substring with Concatenation of All Words
查看>>
【一天一道LeetCode】#60. Permutation Sequence.
查看>>
【一天一道LeetCode】#62. Unique Paths
查看>>
【一天一道LeetCode】#61. Rotate List
查看>>
【一天一道LeetCode】#63. Unique Paths II
查看>>
【一天一道LeetCode】#36. Valid Sudoku
查看>>
【一天一道LeetCode】#75. Sort Colors
查看>>
【一天一道LeetCode】#76. Minimum Window Substring
查看>>
【计算机网络 第五版】阅读笔记之一:概述
查看>>
【计算机网络 第五版】阅读笔记之二:物理层
查看>>
【一天一道LeetCode】#83. Remove Duplicates from Sorted List
查看>>
【一天一道LeetCode】#91. Decode Ways
查看>>
【一天一道LeetCode】#92. Reverse Linked List II
查看>>
【一天一道LeetCode】#93. Restore IP Addresses
查看>>
【一天一道LeetCode】#94. Binary Tree Inorder Traversal
查看>>