zoukankan      html  css  js  c++  java
  • 图片压缩

    一.图片的存在形式

    1.文件形式(即以二进制形式存在于硬盘上)
    2.流的形式(即以二进制形式存在于内存中)
    3.Bitmap形式
    这三种形式的区别: 文件形式和流的形式对图片体积大小并没有影响,也就是说,如果手机SD卡上的如果是100K,那么通过流的形式读到内存中,也一定是占100K的内存,注意是流的形式,不是Bitmap的形式。当图片以Bitmap的形式存在时,其占用的内存会瞬间变大, 我试过55K的jpg文件加载到内存以Bitmap形式存在时,占用内存达到3M,关于Bitmap内存占用的问题我会再写一篇博客专门研究。
     
    检测图片三种形式大小的方法:
    文件形式: file.length()
    流的形式: 讲图片文件读到内存输入流中,看它的byte数 toByteArray().length
    Bitmap:  bitmap.getByteCount()
     

    二.常见的压缩方式

    第一:我们先看下质量压缩方法:

     1 /**
     2      * 按质量压缩
     3      * @param image
     4      * @return
     5      */
     6     public static Bitmap compressByQuality(Bitmap image) { 
     7         ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     8         //质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
     9         image.compress(Bitmap.CompressFormat.JPEG, 100, baos); 
    10         int options = 100; //压缩比例
    11       //循环判断如果压缩后图片是否大于100kb,大于继续压缩  
    12         while ( baos.toByteArray().length / 1024>100) {       
    13             baos.reset();//重置baos
    14             //这里压缩options%,把压缩后的数据存放到baos中 
    15             image.compress(Bitmap.CompressFormat.JPEG, options, baos);
    16             options -= 10;//每次都减少10 
    17         } 
    18         //把压缩后的数据baos存放到ByteArrayInputStream中 
    19         ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
    20       //把ByteArrayInputStream数据生成图片 
    21         Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);
    22         return bitmap; 
    23     }

    第二:图片按比例大小压缩方法(根据路径获取图片并压缩):

     1   /**
     2      * 根据图片路径将图片读入内存,同时压缩
     3      * @param srcPath
     4      * @return
     5      */
     6     public static Bitmap compressByPath(String srcPath) {  
     7         BitmapFactory.Options newOpts = new BitmapFactory.Options();  
     8         newOpts.inJustDecodeBounds = true;  //只读宽和高
     9         Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);//此时返回bm为空  
    10            
    11         newOpts.inJustDecodeBounds = false;  
    12         int w = newOpts.outWidth;  
    13         int h = newOpts.outHeight;  
    14         //手机分辨率,可以根据要求设置
    15         float hh = 1280f;
    16         float ww = 720f;
    17         //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可  
    18         int be = 1;//be=1表示不缩放  
    19         if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放  
    20             be = (int) (newOpts.outWidth / ww);  
    21         } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放  
    22             be = (int) (newOpts.outHeight / hh);  
    23         }  
    24         if (be <= 0)  
    25             be = 1;  
    26         newOpts.inSampleSize = be;//设置缩放比例  
    27         //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了  
    28         bitmap = BitmapFactory.decodeFile(srcPath, newOpts);  
    29         return bitmap;
    30     }

    第三:图片按比例大小压缩方法(根据Bitmap图片压缩):

     1   /**
     2      * 按像素压缩
     3      * @param image
     4      * @return
     5      */
     6     public static Bitmap compressByPixel(Bitmap image) {  
     7         ByteArrayOutputStream baos = new ByteArrayOutputStream();         
     8         image.compress(Bitmap.CompressFormat.JPEG, 100, baos);  
     9         //判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出  
    10         if( baos.toByteArray().length / 1024>1024) {  
    11             baos.reset();//重置baos即清空baos  
    12           //这里压缩50%,把压缩后的数据存放到baos中  
    13             image.compress(Bitmap.CompressFormat.JPEG, 50, baos);
    14         }  
    15         ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());  
    16         BitmapFactory.Options newOpts = new BitmapFactory.Options();  
    17         //开始读入图片,此时把options.inJustDecodeBounds 设回true了  
    18         newOpts.inJustDecodeBounds = true;  
    19         Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);  
    20         newOpts.inJustDecodeBounds = false;  
    21         int w = newOpts.outWidth;  
    22         int h = newOpts.outHeight;  
    23        //手机分辨率,可以根据要求设置
    24         float hh = 1280f;
    25         float ww = 720f;
    26         //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可  
    27         int be = 1;//be=1表示不缩放  
    28         if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放  
    29             be = (int) (newOpts.outWidth / ww);  
    30         } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放  
    31             be = (int) (newOpts.outHeight / hh);  
    32         }  
    33         if (be <= 0)  
    34             be = 1;  
    35         newOpts.inSampleSize = be;//设置缩放比例  
    36         //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了  
    37         isBm = new ByteArrayInputStream(baos.toByteArray());  
    38         bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);  
    39         return bitmap;
    40     }  
  • 相关阅读:
    一些常用的正则表达式
    ASP.net国际化页面可以选择输出语言
    SQL 2008 数据表导入到 ORACLE 10g
    转载 SQL Server 2008中增强的汇总技巧
    类似于行转列的一种需求
    第一次
    很奇怪的一个SQL 语句
    MS SQL 中 FULL JOIN 的用法
    [转载]网络编辑必知常识:什么是PV、UV和PR值 zz
    寒假学习2实验一Linux系统的安装和常用命令
  • 原文地址:https://www.cnblogs.com/allin1579/p/4942084.html
Copyright © 2011-2022 走看看