首页 > 其他 > 详细

图片压缩

时间:2020-03-15 13:40:10      阅读:55      评论:0      收藏:0      [点我收藏+]

申明:低级码农问题解决中的参考和解决后的小结,仅用于个人记录,能力有限,可能有些错误,缺陷不自知,欢迎在评论中指正,谢谢!

 

参考:

质量压缩方法:https://www.jianshu.com/p/3ac26611bc0d

图片有损压缩与无损压缩对比:https://zhidao.baidu.com/question/214587137.html

 

图片压缩的目的,是为了减小图片体积,即磁盘占用空间。包括一下几种。

1/质量压缩

   质量压缩不会减少图片的像素,它是在保持像素的前提下改变图片的位深及透明度,来达到压缩图片的目的,图片的长,宽像素都不会改变,那么bitmap所占内存大小是不会变的。

  质量压缩有个关键参数:quality,可以调节你压缩的比例,要注意一点就是,质量压缩对png格式这种图片没有作用,因为png是无损压缩。quality与压缩后的文件大小不是线性关系。另外有个奇怪现象是,手机拍摄的jpg图片,经过质量100的压缩后,图片体积反而略有增加,我理解的是,相机的压缩算法比java原生压缩算法更优,所以压缩后的体积更小。

  质量压缩的核心方法在android.graphics.Bitmap中,如下

    /**
     * @param format    压缩格式,包含JPEG,PNG,WEBP
     * @param quality   压缩比例,低于80会导致图片质量肉眼可见的变差,太高又会导致体积减小不明显
     * @param stream
     * @return
     */
    abstract boolean compress(Bitmap.CompressFormat format, int quality, OutputStream stream);

  质量压缩方法如下:

 1     private void compress(String inputPath, String outputPath) {
 2         Bitmap originBitmap = BitmapFactory.decodeFile(inputPath);
 3         try {
 4             FileOutputStream fos = new FileOutputStream(new File(outputPath));
 5             BufferedOutputStream bos = new BufferedOutputStream(fos);
 6             originBitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);
 7             bos.close();
 8         } catch (IOException e) {
 9         }
10     }

2/采样率压缩

  是将图片读取到内存时,降低采样率。关键参数是BitmapFactory.Options.inSampleSize。当isSampleSize=2时,即xy方向,分别每2个点取一个点,图片写入内存大小占原理的1/4。。当isSampleSize=3时,即xy方向,分别每3个点取一个点,图片写入内存大小占原理的1/9

  采样率压缩是减小图片写入内存时占用的内存大小,实际一般通过与质量压缩配合使用,来进一步压缩图片体积。经过采样率压缩后的图片,宽高都会减小(只有原来的isSampleSize分之一),压缩后的图片在写入内存,占用内存空间也会减小。

 1 BitmapFactory.Options options = new BitmapFactory.Options();
 2 options.inSampleSize = inSampleSize;
 3 Bitmap originBitmap = BitmapFactory.decodeFile(inputPath, options);
 4 try {
 5     FileOutputStream fos = new FileOutputStream(new File(outputPath));
 6     BufferedOutputStream bos = new BufferedOutputStream(fos);
 7     originBitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);
 8 } catch (IOException e) {
 9 
10 }

 

3/通过Matrix压缩

  Matrix压缩的原理是将图片的bitmap读入内存,然后通过matrix缩放比来创建一个新的bitmapMatrix压缩的处理结果与采样率压缩类似,都可以改变压缩后的图片的宽高,体积。但他们的实现过程有很大的差异。1/采样率压缩是文件写入内存过程中,matrix是先写入一个完整的bitmap,再对这个bitmap变换生成一个新的bitmap

  Matrix的优势是可以设置任何比例的压缩,可以不用保持长宽比来自由压缩。甚至可以通过裁剪来压缩,这种情况我们不讨论。Matrix的劣势是需要将图片的bitmap先读入内存,可能导致内存溢出,不像采样率那样,可以通过参数预读。

 1 Bitmap originBitmap = BitmapFactory.decodeFile(inputPath);
 2 Matrix matrix = new Matrix();
 3 matrix.setScale(scale, scale);
 4 originBitmap = Bitmap.createBitmap(originBitmap, 0, 0, originBitmap.getWidth(), originBitmap.getHeight(), matrix, true);
 5 try {
 6     FileOutputStream fos = new FileOutputStream(new File(outputPath));
 7     BufferedOutputStream bos = new BufferedOutputStream(fos);
 8     originBitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);
 9 } catch (IOException e) {
10 
11 }

4/编码格式压缩

  这种方式是减小图片占用的内存空间。Android将图片写入内存,默认编码格式是ARGB8888,一像素将用4个字节。如果采用其他编码格式,如RGB565,一像素只占用2个字节,可以减小内存占用空间。

  有个奇怪的现象是,先通过编码格式压缩,再质量压缩生成的图片文件,比不先经过编码格式压缩,直接质量压缩生成的图片文件生成的文件要大。原因不明。

 1 BitmapFactory.Options options = new BitmapFactory.Options();
 2 options.inPreferredConfig = Bitmap.Config.RGB_565;
 3 Bitmap originBitmap = BitmapFactory.decodeFile(inputPath, options);
 4 try {
 5     FileOutputStream fos = new FileOutputStream(new File(outputPath));
 6     BufferedOutputStream bos = new BufferedOutputStream(fos);
 7     originBitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);
 8 } catch (IOException e) {
 9 
10 }

 

 在解决问题中,查阅了解了一些图片相关知识,更有利于了解图片压缩的过程和选择,有兴趣请移步:https://www.cnblogs.com/hellodingc/p/12497042.html

 

 

图片压缩

原文:https://www.cnblogs.com/hellodingc/p/12497042.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!