android图片压缩总结

首先该文章是总结, 不是原创, 是通过看网上其他大神的文章和自己的一些实践总结出来的.

一.图片的存在形式

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 plaincopy

  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形式的图片, 后果可想而知

[java] view plaincopy

  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. }

再看一个方法:

[java] view plaincopy

  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的像素, 从而减少了它所占用的内存

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

android图片压缩总结

时间: 2024-10-25 14:31:36

android图片压缩总结的相关文章

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

android 图片压缩方法: 第一:质量压缩法: private Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArrayOutputStream();        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中        int options = 100

Android图片压缩(质量压缩和尺寸压缩)

在网上调查了图片压缩的方法并实装后,大致上可以认为有两类压缩:质量压缩(不改变图片的尺寸)和尺寸压缩(相当于是像素上的压缩):质量压缩一般可用于上传大图前的处理,这样就可以节省一定的流量,毕竟现在的手机拍照都能达到3M左右了,尺寸压缩一般可用于生成缩略图.两种方法都实装在了我的项目中,结果却发现在质量压缩的模块中,本来1.9M的图片压缩后反而变成3M多了,很是奇怪,再做了进一步调查终于知道原因了.下面这个博客说的比较清晰: android图片压缩总结 总结来看,图片有三种存在形式:硬盘上时是fi

Android图片压缩技巧

请尊重他人的劳动成果,转载请注明出处:Android图片压缩技巧 http://blog.csdn.net/fengyuzhengfan/article/details/41759835 当需要将Android客户端的图片上传到服务器时,往往需要将图片进行压缩,关于图片的压缩方法,小编分享几种常用的方式: 第一种方式:裁切以达到压缩的目的 我曾在<Android开发之裁剪照片>一文中详细介绍过如何裁切照片,感兴趣的朋友可以去看一下. 第二种方式:将图片进行降质处理(即降低图片的质量)以达到压缩

android图片压缩方法

第一:我们先看下质量压缩方法 private Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中 int options = 100; while ( baos.toByteArra

android图片压缩上传系列-service篇

本篇文章是继续上篇android图片压缩上传系列-基础篇文章的续篇.主要目的是:通过Service来执行图片压缩任务来讨论如何使用Service,如何处理任务量大的并发问题. 了解下Service 大家都知道如果有费时任务,这时需要将任务放到后台线程中执行,如果对操作的结果需要通过ui展示还需要在任务完成后通知前台更新.当然对于这种情况,大家也可以在Activity中启动线程,在线程中通过Handler和sendMessage来通知Activity并执行更新ui的操作,但是更好的方法是将这些操作

android图片压缩质量参数Bitmap.Config RGB_565等的含义

android图片压缩质量参数 在实用ImageLoader中,在配置DisplayImageOptions时,需要设置.bitmapConfig(Bitmap.Config.RGB_565) 那么这个 Bitmap.Config.RGB_565 是什么意思呢 ? 在android中的大图片一般都要经过压缩才能显示,不然容易发生oom,一般我们压缩的时候都只关注其尺寸方面的大小,其实除了尺寸之外,影响一个图片占用空间的还有其色彩细节. 打开Android.graphics.Bitmap类里有一个

Android图片压缩方法总结

本文总结Android应用开发中三种常见的图片压缩方法,分别是:质量压缩法.比例压缩法(根据路径获取图片并压缩)和比例压缩法(根据Bitmap图片压缩). 第一:质量压缩方法: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 private Bitmap compressImage(Bitmap image) {           ByteArrayOutputStream baos = new ByteArrayOutputStream();         image

(转)Android图片压缩方法总结

本文总结Android应用开发中三种常见的图片压缩方法,分别是:质量压缩法.比例压缩法(根据路径获取图片并压缩)和比例压缩法(根据Bitmap图片压缩). http://www.open-open.com/lib/view/open1413862305997.html 第一:质量压缩方法: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 private Bitmap compressImage(Bitmap image) {           ByteArrayOutpu

android 图片压缩

图片压缩BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = false; options.inPurgeable = true; options.inInputShareable = true; // Do not compress options.inSampleSize = 1; options.inPreferredConfig = Config.ARGB_888