`

android图片压缩总结

 
阅读更多

转自: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()(API 19) = bitmap.getRowBytes() * bitmap.getHeight()
 

二.常见的压缩方式

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.   
  6.         newOpts.inJustDecodeBounds = false;  
  7.         int w = newOpts.outWidth;  
  8.         int h = newOpts.outHeight;  
  9.         float hh = 800f;//  
  10.         float ww = 480f;//  
  11.         int be = 1;  
  12.         if (w > h && w > ww) {  
  13.             be = (int) (newOpts.outWidth / ww);  
  14.         } else if (w < h && h > hh) {  
  15.             be = (int) (newOpts.outHeight / hh);  
  16.         }  
  17.         if (be <= 0)  
  18.             be = 1;  
  19.         newOpts.inSampleSize = be;//设置采样率  
  20.           
  21.         newOpts.inPreferredConfig = Config.ARGB_8888;//该模式是默认的,可不设  
  22.         newOpts.inPurgeable = true;// 同时设置才会有效  
  23.         newOpts.inInputShareable = true;//。当系统内存不够时候图片自动被回收  
  24.           
  25.         bitmap = BitmapFactory.decodeFile(srcPath, newOpts);  
  26. //      return compressBmpFromBmp(bitmap);//原来的方法调用了这个方法企图进行二次压缩  
  27.                                     //其实是无效的,大家尽管尝试  
  28.         return bitmap;  
  29.     }  


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

总结: 要想压缩内存中的Bitmap, 就要减少它的像素; 要想压缩为File, 就要降低它的质量

 

    Matrix压缩法

public void transImage(String fromFile, int width, int height) {
		Bitmap bitmap = BitmapFactory.decodeFile(fromFile);
		int bitmapWidth = bitmap.getWidth();
		int bitmapHeight = bitmap.getHeight();

		// 缩放图片的尺寸
		float scaleWidth = (float) width / bitmapWidth;
		float scaleHeight = (float) height / bitmapHeight;
		Matrix matrix = new Matrix();
		matrix.postScale(scaleWidth, scaleHeight);

		// 产生缩放后的Bitmap对象
		Bitmap resizeBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmapWidth,
				bitmapHeight, matrix, false);

		if (!bitmap.isRecycled()) {
			bitmap.recycle();// 记得释放资源,否则会内存溢出
		}
		if (!resizeBitmap.isRecycled()) {
			resizeBitmap.recycle();
		}
	}

 

 ThumbnailUtils压缩法(android 2.2开始加入)

该类提供了三种静态方法可以直接调用获取。

   static Bitmap  createVideoThumbnail(String filePath, int kind)  //获取视频文件的缩略图,第一个参数为视频文件的位置,比如/sdcard/android123.3gp,而第二个参数可以为MINI_KIND或MICRO_KIND最终和分辨率有关 
   static Bitmap  extractThumbnail(Bitmap source, int width, int height, int options)  //直接对Bitmap进行缩略操作,最后一个参数定义为OPTIONS_RECYCLE_INPUT ,来回收资源
   static Bitmap  extractThumbnail(Bitmap source, int width, int height) // 这个和上面的方法一样,无options选项

 

内存里面的Bitmap都是无压缩的,而我们保存的File一般都是经过压缩的,所以,将File读取到内存中会大很多。

只有bitmap.compress()方法是可以把bitmap写到File中的,此方法的压缩是质量压缩,即图片像素不变,减少每个点所保存的信息量来达到压缩的目的,保存下来的File的大小会变小,将压缩的File读取到内存中的Bitmap对象时,所占用的内存跟没压缩的是一样大小,即bitmap的像素多少不变,图片会失真。

SampleSize取样压缩, Matrix矩阵压缩,ThumbnailUtils(实际上也是矩阵压缩)都是对内存中的Bitmap进行压缩,会改变Bitmap的大小,即改变Bitmap的像素大小,得到一个新的压缩过的bitmap。

android 2.2开始,有一个类ThumbnailUtils用来处理图像压缩。

分享到:
评论

相关推荐

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

    在网上调查了图片压缩的方法并实装后,大致上可以认为有两类压缩:...android图片压缩总结 总 结来看,图片有三种存在形式:硬盘上时是file,网络传输时是stream,内存中是stream或bitmap,所谓的质量压缩,它其实只能

    Android高效压缩图片不失真的方法总结

    在Android开发中,图片压缩是一项常见的任务,尤其在移动设备上,为了节省存储空间和提高应用性能,高效压缩图片而不失真是必要的。本篇文章将详细总结Android中实现这一目标的方法和策略。 首先,理解图片压缩的...

    android图片压缩终极方案

    总结来说,“android图片压缩终极方案”是一个利用NDK和JPEG库哈夫曼算法的高效图片压缩解决方案,旨在在不牺牲图像质量的前提下,最小化文件大小。对于需要处理大量图片或对性能有严格要求的Android应用来说,这样...

    Android图片质量压缩

    总结来说,Android图片质量压缩涉及到了图片的加载、压缩、保存以及上传等多个环节。开发者可以根据实际需求,灵活运用各种工具和方法来实现高效且节省资源的图片处理。在处理大量图片时,合理使用缓存和第三方库...

    Android压缩图片,图片质量不变

    总结,Android图片压缩的关键在于找到合适的压缩算法、压缩质量与文件大小之间的平衡。在不改变图片质量的前提下压缩图片,需要尝试不同的压缩策略,如调整JPEG或PNG的压缩质量,或者利用第三方库提供的高级功能。...

    Android 图片压缩不OOM,超高保真度

    通过分析和学习这个示例,开发者可以更好地理解和掌握Android图片压缩的技巧,以达到在不引发OOM的前提下,保持图片的高保真度。 总结来说,处理Android中的大图,我们需要合理地使用`BitmapFactory.Options`进行...

    Android基于JNI压缩图片高效不失真

    总结,基于JNI的图片压缩方法结合了Java的易用性和C/C++的高性能,为Android应用提供了高效不失真的图片压缩解决方案。同时,开发者也可以根据实际需求选择不同的图像处理库,如OpenCV、libjpeg等,来优化压缩算法。

    图片压缩节约内存

    总结一下,图片压缩是为了优化内存使用,防止内存溢出,并提升应用性能。在Android开发中,我们可以使用BitmapFactory的decode方法配合缩放比例,或者Bitmap的compress方法进行压缩。对于大量图片的显示,利用异步...

    Android下的图片压缩及图片和视频的上传

    本文将深入探讨Android环境下如何实现图片压缩以及如何将压缩后的图片和视频上传到服务器。 一、图片压缩 1. 图片压缩原理: 图片压缩的基本思路是减少图片的数据量,而不会显著降低其视觉质量。这通常通过降低...

    libjpeg android图片无损压缩

    总结来说,libjpeg在Android上的无损图片压缩涉及到库的集成、JNI接口编写、压缩参数的设置以及实际的编码过程。理解这些步骤和细节,开发者就能更好地控制图片的质量和大小,从而提升应用的用户体验。

    Android图片压缩、加水印

    总结,Android图片压缩和加水印是提高应用性能和保护版权的重要手段。开发者可以根据项目需求选择合适的方法,结合Android SDK和第三方库来实现高效、美观的功能。在AddWatermark-master这个项目中,你可能找到更...

    Android之图片压缩

    总结来说,Android图片压缩是提升应用性能和用户体验的重要手段。通过调整图片尺寸、位深和使用高效的压缩算法,可以有效减小图片大小,同时保证视觉效果。在实际开发中,应结合各种策略,确保图片压缩既高效又灵活...

    Android 图片压缩与解压的方法

    总结,Android图片压缩与解压涉及多个环节,包括选择合适的压缩格式、控制Bitmap大小、解压文件、存储管理和高效显示。开发者需要结合具体需求,灵活运用Android Studio提供的工具和第三方库,确保应用在处理图片时...

    android图片处理总结

    以下是对Android图片处理的一些关键知识点的详细阐述: 1. **图片加载**:在Android中,Bitmap是用于表示图片的基础类。然而,直接从磁盘或网络加载大图可能会导致内存溢出。因此,我们通常使用图片库如Glide、...

    android图片无损压缩

    总结来说,Android图片无损压缩是一项涉及图像处理、数据编码和性能优化的综合技术。开发者需要根据应用场景选择合适的压缩方法,并结合各种优化策略,以实现最佳的压缩效果。通过学习和掌握这些技术,可以提升应用...

    Android 拍照和相册选取+图片压缩功能

    总结,Android应用开发中,拍照、相册选取和图片压缩是非常常见的需求。通过上述步骤,开发者可以轻松实现这些功能,提升用户体验。同时,合理利用第三方库如Luban,能有效提高开发效率和代码质量。在实际项目中,...

    Android图片的压缩与缓存

    本篇将深入探讨Android图片的压缩与缓存机制,以提高应用性能并防止内存溢出。 ### Bitmap对象与内存管理 Bitmap是Android中用于表示图像数据的类,它直接占用大量的内存资源。当加载大尺寸图片时,未进行适当处理...

    android 照相、压缩图片、图片缓存

    - 压缩库:Luboo、 Glide、Picasso等库提供了便捷的图片压缩功能,它们会自动处理内存和磁盘缓存,降低应用内存消耗。 - 位图配置:使用inSampleSize调整 BitmapFactory.Options,以减少加载图片时的内存占用。 -...

    Android图片压缩几种方式总结

    Android 图片压缩几种方式总结 Android 图片压缩是 Android 开发中一个非常重要的知识点,主要是为了防止图片的 OOM(Out of Memory)。图片压缩的方式有很多,下面我们将总结几种常见的 Android 图片压缩方式。 ...

    Android中图片压缩方案详解样本.doc

    本篇文章将详细解析两种常见的Android图片压缩方案:质量压缩法和采样率压缩法。 1. **质量压缩法** 质量压缩法是通过调整图片的位深度和透明度来减小文件大小,而不改变图片的像素数量。这种方法适用于那些对图片...

Global site tag (gtag.js) - Google Analytics