android图片压缩

来源:互联网 发布:淘宝便宜的衣服能买吗 编辑:程序博客网 时间:2024/06/14 10:09

首先该文章是总结, 不是原创, 是通过看网上其他大神的文章和自己的一些实践总结出来的.
一.图片的存在形式
1.文件形式(即以二进制形式存在于硬盘上)
2.流的形式(即以二进制形式存在于内存中)
3.Bitmap形式
这三种形式的区别: 文件形式和流的形式对图片体积大小并没有影响,也就是说,如果你手机SD卡上的如果是100K,那么通过流的形式读到内存中,也一定是占100K的内存,注意是流的形式,不是Bitmap的形式,当图片以Bitmap的形式存在时,其占用的内存会瞬间变大, 我试过500K文件形式的图片加载到内存,以Bitmap形式存在时,占用内存将近10M,当然这个增大的倍数并不是固定的

检测图片三种形式大小的方法:
文件形式: file.length()
流的形式: 讲图片文件读到内存输入流中,看它的byte数
Bitmap: bitmap.getByteCount()

二.常见的压缩方式
1. 将图片保存到本地时进行压缩, 即将图片从Bitmap形式变为File形式时进行压缩,
特点是: File形式的图片确实被压缩了, 但是当你重新读取压缩后的file为 Bitmap是,它占用的内存并没有改变

[java] view plain copy 在CODE上查看代码片派生到我的代码片public static void compressBmpToFile(Bitmap bmp,File file){          ByteArrayOutputStream baos = new ByteArrayOutputStream();          int options = 80;//个人喜欢从80开始,          bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);          while (baos.toByteArray().length / 1024 > 100) {               baos.reset();              options -= 10;              bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);          }          try {              FileOutputStream fos = new FileOutputStream(file);              fos.write(baos.toByteArray());              fos.flush();              fos.close();          } catch (Exception e) {              e.printStackTrace();          }      }  

方法说明: 该方法是压缩图片的质量, 注意它不会减少图片的像素,比方说, 你的图片是300K的, 1280*700像素的, 经过该方法压缩后, File形式的图片是在100以下, 以方便上传服务器, 但是你BitmapFactory.decodeFile到内存中,变成Bitmap时,它的像素仍然是1280*700, 计算图片像素的方法是 bitmap.getWidth()和bitmap.getHeight(), 图片是由像素组成的, 每个像素又包含什么呢? 熟悉PS的人知道, 图片是有色相,明度和饱和度构成的.

该方法的官方文档也解释说, 它会让图片重新构造, 但是有可能图像的位深(即色深)和每个像素的透明度会变化,JPEG onlysupports opaque(不透明), 也就是说以jpeg格式压缩后, 原来图片中透明的元素将消失.所以这种格式很可能造成失真

既然它是改变了图片的显示质量, 达到了对File形式的图片进行压缩, 图片的像素没有改变的话, 那重新读取经过压缩的file为Bitmap时, 它占用的内存并不会少.(不相信的可以试试)

因为: bitmap.getByteCount() 是计算它的像素所占用的内存, 请看官方解释: Returns the number of bytes used to store this bitmap’s pixels.

  1. 将图片从本地读到内存时,进行压缩 ,即图片从File形式变为Bitmap形式
    特点: 通过设置采样率, 减少图片的像素, 达到对内存中的Bitmap进行压缩
    先看一个方法: 该方法是对内存中的Bitmap进行质量上的压缩, 由上面的理论可以得出该方法是无效的, 而且也是没有必要的,因为你已经将它读到内存中了,再压缩多此一举, 尽管在获取系统相册图片时,某些手机会直接返回一个Bitmap,但是这种情况下, 返回的Bitmap都是经过压缩的, 它不可能直接返回一个原声的Bitmap形式的图片, 后果可想而知
[java] view plain copy 在CODE上查看代码片派生到我的代码片private Bitmap compressBmpFromBmp(Bitmap image) {          ByteArrayOutputStream baos = new ByteArrayOutputStream();          int options = 100;          image.compress(Bitmap.CompressFormat.JPEG, 100, baos);          while (baos.toByteArray().length / 1024 > 100) {               baos.reset();              options -= 10;              image.compress(Bitmap.CompressFormat.JPEG, options, baos);          }          ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());          Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);          return bitmap;      }  

再看一个方法:

[java] view plain copy 在CODE上查看代码片派生到我的代码片    private Bitmap compressImageFromFile(String srcPath) {          BitmapFactory.Options newOpts = new BitmapFactory.Options();          newOpts.inJustDecodeBounds = true;//只读边,不读内容          Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);          newOpts.inJustDecodeBounds = false;          int w = newOpts.outWidth;          int h = newOpts.outHeight;          float hh = 800f;//          float ww = 480f;//          int be = 1;          if (w > h && w > ww) {              be = (int) (newOpts.outWidth / ww);          } else if (w < h && h > hh) {              be = (int) (newOpts.outHeight / hh);          }          if (be <= 0)              be = 1;          newOpts.inSampleSize = be;//设置采样率          newOpts.inPreferredConfig = Config.ARGB_8888;//该模式是默认的,可不设          newOpts.inPurgeable = true;// 同时设置才会有效          newOpts.inInputShareable = true;//。当系统内存不够时候图片自动被回收          bitmap = BitmapFactory.decodeFile(srcPath, newOpts);  //      return compressBmpFromBmp(bitmap);//原来的方法调用了这个方法企图进行二次压缩                                      //其实是无效的,大家尽管尝试          return bitmap;      }  

方法说明: 该方法就是对Bitmap形式的图片进行压缩, 也就是通过设置采样率, 减少Bitmap的像素, 从而减少了它所占用的内存

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 高中没考上家人让打工怎么办 一建证书丢了怎么办 自考大专证书丢了怎么办 护士学分卡丢了怎么办 公司电脑只能用内网怎么办 遇见素质低的人怎么办 被素质低的人骂怎么办 对素质差的人怎么办 碰到素质低的人怎么办 和韩国人结婚后工作怎么办 大连明珠卡坏了怎么办 护肤品酒精含量太高怎么办 父母出国三年想孩子怎么办 孩子高考不理想想出国怎么办 交大附中创新班剩余孩子怎么办 棋牌开发公司倒闭了怎么办 7月1日本地流量怎么办 装电池的弹簧生锈了怎么办 电器被电池碱了怎么办 车辆被交警拖走怎么办 香烟熏的眼睛疼怎么办 想在中牟住5天怎么办 腰弯了直不了怎么办 自考科目停考了怎么办 把wlan密码忘了怎么办 滕州不给报新婚怎么办 体内锁水能力差怎么办 别人说你人品差怎么办 面对没素质的人怎么办 遇到很坏的室友怎么办 餐饮员工与顾客发生矛盾怎么办 新员工老员工出现矛盾怎么办 手机移动4g网慢怎么办 碰到素质低的老公怎么办 小孩做事拖拉 没时间观念怎么办 execl表中日期加3.5怎么办 狗狗喜欢咬人怎么办 烧烤一顿吃多了怎么办 派派背包食物不足怎么办 未转变者下不了怎么办 小升初户籍与房产不一致怎么办