原文地址:http://blog.csdn.net/cherry609195946/article/details/9264409

一.图片的存在形式

1.文件形式(即以二进制形式存在于硬盘上)
2.流的形式(即以二进制形式存在于内存中)
3.Bitmap形式
这三种形式的区别: 文件形式和流的形式对图片体积大小并没有影响,也就是说,如果你手机SD卡上的如果是100K,那么通过流的形式读到内存中,也一定是占100K的内存,注意是流的形式,不是Bitmap的形式,当图片以Bitmap的形式存在时,其占用的内存会瞬间变大, 我试过500K文件形式的图片加载到内存,以Bitmap形式存在时,占用内存将近10M,当然这个增大的倍数并不是固定的
 
检测图片三种形式大小的方法:
文件形式: file.length()
流的形式: 讲图片文件读到内存输入流中,看它的byte数
Bitmap:    bitmap.getByteCount()
 

二.常见的压缩方式

1. 将图片保存到本地时进行压缩, 即将图片从Bitmap形式变为File形式时进行压缩,
    特点是:  File形式的图片确实被压缩了, 但是当你重新读取压缩后的file为 Bitmap是,它占用的内存并没有改变   
  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. }
方法说明: 该方法是压缩图片的质量, 注意它不会减少图片的像素,比方说, 你的图片是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.
 

2.   将图片从本地读到内存时,进行压缩 ,即图片从File形式变为Bitmap形式

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

再看一个方法:

  1. private Bitmap compressImageFromFile(String srcPath) {
  2. BitmapFactory.Options newOpts = new BitmapFactory.Options();
  3. newOpts.inJustDecodeBounds = true;//只读边,不读内容
  4. Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
  5. newOpts.inJustDecodeBounds = false;
  6. int w = newOpts.outWidth;
  7. int h = newOpts.outHeight;
  8. float hh = 800f;//
  9. float ww = 480f;//
  10. int be = 1;
  11. if (w > h && w > ww) {
  12. be = (int) (newOpts.outWidth / ww);
  13. } else if (w < h && h > hh) {
  14. be = (int) (newOpts.outHeight / hh);
  15. }
  16. if (be <= 0)
  17. be = 1;
  18. newOpts.inSampleSize = be;//设置采样率
  19. newOpts.inPreferredConfig = Config.ARGB_8888;//该模式是默认的,可不设
  20. newOpts.inPurgeable = true;// 同时设置才会有效
  21. newOpts.inInputShareable = true;//。当系统内存不够时候图片自动被回收
  22. bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
  23. //      return compressBmpFromBmp(bitmap);//原来的方法调用了这个方法企图进行二次压缩
  24. //其实是无效的,大家尽管尝试
  25. return bitmap;
  26. }
方法说明: 该方法就是对Bitmap形式的图片进行压缩, 也就是通过设置采样率, 减少Bitmap的像素, 从而减少了它所占用的内存

(转)android图片压缩总结的更多相关文章

  1. Android 图片压缩、照片选择、裁剪,上传、一整套图片解决方案

    1.Android一整套图片解决方案 http://mp.weixin.qq.com/s?__biz=MzAxMTI4MTkwNQ==&mid=2650820998&idx=1& ...

  2. android图片压缩方法

    android 图片压缩方法: 第一:质量压缩法: private Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = ...

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

    android 图片压缩方法: 第一:质量压缩法: private Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = ...

  4. Android 图片压缩器

    概述 Android 图片压缩器:一款高效的图片压缩器库,支持批量压缩,异步压缩.多线程多任务压缩,压缩比设置等特性. 详细 代码下载:http://www.demodashi.com/demo/12 ...

  5. Android 图片压缩各种方式

       前言:由于公司项目当中需要用到压缩这块的相应技术,之前也做过的图片压缩都不是特别的理想, 所以这次花了很多心思,仔细研究和在网上找到了很多相对应的资料.为了就是 以后再做的时候直接拿来用就可以了 ...

  6. Android图片压缩上传(二)

    之前有用到libjpeg,还是有一定的局限性,最近用了一个新的方式,效果还是挺不错,随着作者的版本更新,Bug也随之变少,目前项目中运用已上线. 1.之前的方式Android图片压缩,不失真,上线项目 ...

  7. Android图片压缩方法总结

    本文总结Android应用开发中三种常见的图片压缩方法,分别是:质量压缩法.比例压缩法(根据路径获取图片并压缩)和比例压缩法(根据Bitmap图片压缩).   第一:质量压缩方法:   ? 1 2 3 ...

  8. Android图片压缩

    import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java ...

  9. 性能优化——Android图片压缩与优化的几种方式

    图片优化压缩方式大概可以分为以下几类:更换图片格式,质量压缩,采样率压缩,缩放压缩,调用jpeg压缩等1.设置图片格式Android目前常用的图片格式有png,jpeg和webp,png:无损压缩图片 ...

  10. android图片压缩总结

    一.bitmap 图片格式介绍 android中图片是以bitmap形式存在的,那么bitmap所占内存,直接影响到了应用所占内存大小,首先要知道bitmap所占内存大小计算方式: bitmap内存大 ...

随机推荐

  1. from live writer

    <body> <div class="pagination"> <a href="#" class="first&quo ...

  2. jsp七大动作和三大指令

    一:include 动态包含(分别编译):用jsp:include动作实现<jsp: include page="included.jsp" flush="true ...

  3. json的中括号和大括号的使用?

    参考这篇文章: http://www.cnblogs.com/sgdkg/archive/2012/12/03/2799723.html json 变量有两种可能, 可能是一个对象, (类似 类的实例 ...

  4. Unity API

    关于 int Mathf.PingPong(t, length); 原理,相当于 #include <iostream> #include <vector> int test( ...

  5. 用jinja做了个E-Letter小项目

    做了一个html E-Letter项目. 邮件模板采用jinja2, html 邮件内容生成简直太爽了. 整个项目开发只用了2个小时, 调试却花了大半天时间, 生成的邮件总是发不出去. 于是, 打开 ...

  6. 详解SESSION与COOKIE的区别

    在PHP面试中 经常碰到请阐述session与cookie的区别与联系,以及如何修改两者的有效时间. 大家都知道,session是存储在服务器端的,cookie是存储在客户端的,session依赖于c ...

  7. A funny story in regard to a linux newbie

    ZZ from here :  ask what kernel ring buffer is A few days ago I started thinking that my linux educa ...

  8. iOS:使用MVC模式帮ViewController瘦身

    如何给UIViewController瘦身 随着程序逻辑复杂度的提高,你是否也发现了App中一些ViewController的代码行数急剧增多,达到了2,3千行,甚至更多.这时如果想再添加一点功能或者 ...

  9. codevs4096 删数问题

    题目描述 Description 键盘输入一个高精度的正整数N,去掉其中任意S个数字后剩下的数字按原左右次序将组成一个新的正整数.编程对给定的N 和S,寻找一种方案使得剩下的数字组成的新数最小. 输入 ...

  10. Memcached原理分析

    Memcached的内存管理方式 Memcached采用了名为Slab Allocation的机制分配,管理内存. Slab Allocation的原理相当简单.将分配的内存分割成各种尺寸的块(chu ...