请尊重他人的劳动成果,转载请注明出处:Android图片压缩技巧

http://blog.csdn.net/fengyuzhengfan/article/details/41759835

当需要将Android客户端的图片上传到服务器时,往往需要将图片进行压缩,关于图片的压缩方法,小编分享几种常用的方式:

第一种方式:裁切以达到压缩的目的

我曾在《Android开发之裁剪照片》一文中详细介绍过如何裁切照片,感兴趣的朋友可以去看一下。


第二种方式:将图片进行降质处理(即降低图片的质量)以达到压缩的目的

这种方式也是比较常用的方式,下面就为大家介绍如何对图片进行降质:

将图片降质我们可以使用Bitmap的这个方法:boolean android.graphics.Bitmap.compress(CompressFormat format, int quality, OutputStream stream)

其中,参数format表示压缩后的格式,quality压缩后的图片质量(0表示最低,100表示不压缩),stream表示要将压缩后的图片保存到的输出流。

下面是详细代码:

/** * 多线程压缩图片的质量 * @author JPH * @param bitmap 内存中的图片 * @param imgPath 图片的保存路径 * @date 2014-12-5下午11:30:43 */public static void compressImageByQuality(final Bitmap bitmap,final String imgPath){new Thread(new Runnable() {//开启多线程进行压缩处理@Overridepublic void run() {// TODO Auto-generated method stubByteArrayOutputStream baos = new ByteArrayOutputStream();options = 100;bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//质量压缩方法,把压缩后的数据存放到baos中 (100表示不压缩,0表示压缩到最小)while (baos.toByteArray().length / 1024 > 100) {//循环判断如果压缩后图片是否大于100kb,大于继续压缩         baos.reset();//重置baos即让下一次的写入覆盖之前的内容 options -= 10;//图片质量每次减少10if(options<0)options=0;//如果图片质量小于10,则将图片的质量压缩到最小值bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//将压缩后的图片保存到baos中if(options==0)break;//如果图片的质量已降到最低则,不再进行压缩}try {FileOutputStream fos = new FileOutputStream(new File(imgPath));//将压缩后的图片保存的本地上指定路径中fos.write(baos.toByteArray());fos.flush();fos.close();} catch (Exception e) {e.printStackTrace();}}}).start();}

方法解析:

由于此方法中包含I/O操作和递归调用比较耗时所以我采用了多线程去处理。


第三种方式:按比例缩小图片的像素以达到压缩的目的

此种方法主要是使用android.graphics.BitmapFactory.Options.Options()方法将图片以指定的采用率加载到内存然后输出到本地以达到压缩像素的目的。

详细代码:

/** * 按比例缩小图片的像素以达到压缩的目的 * @author JPH * @param imgPath * @date 2014-12-5下午11:30:59 */public static void compressImageByPixel(String imgPath) {BitmapFactory.Options newOpts = new BitmapFactory.Options();newOpts.inJustDecodeBounds = true;//只读边,不读内容Bitmap bitmap = BitmapFactory.decodeFile(imgPath, newOpts);newOpts.inJustDecodeBounds = false;int width = newOpts.outWidth;int height = newOpts.outHeight;float maxSize = 1000f;//默认1000pxint be = 1;if (width > height && width > maxSize) {//缩放比,用高或者宽其中较大的一个数据进行计算be = (int) (newOpts.outWidth / maxSize);} else if (width < height && height > maxSize) {be = (int) (newOpts.outHeight / maxSize);}be++;newOpts.inSampleSize = be;//设置采样率newOpts.inPreferredConfig = Config.ARGB_8888;//该模式是默认的,可不设newOpts.inPurgeable = true;// 同时设置才会有效newOpts.inInputShareable = true;//。当系统内存不够时候图片自动被回收bitmap = BitmapFactory.decodeFile(imgPath, newOpts);ByteArrayOutputStream baos = new ByteArrayOutputStream();bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);try {FileOutputStream fos = new FileOutputStream(new File(imgPath));fos.write(baos.toByteArray());fos.flush();fos.close();} catch (Exception e) {e.printStackTrace();}}

第四种方式:将图片先按比例压缩然后再降质

此种方式主要结合第二种和第三种方法以下是详细代码:

/** * 多线程压缩图片的质量 * @author JPH * @param bitmap 内存中的图片 * @param imgPath 图片的保存路径 * @date 2014-12-5下午11:30:43 */public static void compressImageByQuality(final Bitmap bitmap,final String imgPath){new Thread(new Runnable() {//开启多线程进行压缩处理@Overridepublic void run() {// TODO Auto-generated method stubByteArrayOutputStream baos = new ByteArrayOutputStream();options = 100;bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//质量压缩方法,把压缩后的数据存放到baos中 (100表示不压缩,0表示压缩到最小)while (baos.toByteArray().length / 1024 > 100) {//循环判断如果压缩后图片是否大于100kb,大于继续压缩         baos.reset();//重置baos即让下一次的写入覆盖之前的内容 options -= 10;//图片质量每次减少10if(options<0)options=0;//如果图片质量小于10,则将图片的质量压缩到最小值bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//将压缩后的图片保存到baos中if(options==0)break;//如果图片的质量已降到最低则,不再进行压缩}try {FileOutputStream fos = new FileOutputStream(new File(imgPath));//将压缩后的图片保存的本地上指定路径中fos.write(baos.toByteArray());fos.flush();fos.close();} catch (Exception e) {e.printStackTrace();}}}).start();}/** * 按比例缩小图片的像素以达到压缩的目的 * @author JPH * @param imgPath * @date 2014-12-5下午11:30:59 */public static void compressImageByPixel(String imgPath) {BitmapFactory.Options newOpts = new BitmapFactory.Options();newOpts.inJustDecodeBounds = true;//只读边,不读内容Bitmap bitmap = BitmapFactory.decodeFile(imgPath, newOpts);newOpts.inJustDecodeBounds = false;int width = newOpts.outWidth;int height = newOpts.outHeight;float maxSize = 1000f;//默认1000pxint be = 1;if (width > height && width > maxSize) {//缩放比,用高或者宽其中较大的一个数据进行计算be = (int) (newOpts.outWidth / maxSize);} else if (width < height && height > maxSize) {be = (int) (newOpts.outHeight / maxSize);}be++;newOpts.inSampleSize = be;//设置采样率newOpts.inPreferredConfig = Config.ARGB_8888;//该模式是默认的,可不设newOpts.inPurgeable = true;// 同时设置才会有效newOpts.inInputShareable = true;//。当系统内存不够时候图片自动被回收bitmap = BitmapFactory.decodeFile(imgPath, newOpts);compressImageByQuality(bitmap,imgPath);//压缩好比例大小后再进行质量压缩  }


更多相关文章

  1. Android(安卓)Fresco实现图片毛玻璃效果
  2. Android使用开源框架ANDROID-IMAGE-INDICATOR实现图片轮播部署
  3. android从手机内存获得图片并全屏显示
  4. android异步加载图片
  5. 【Android】Android开源项目精选(一)
  6. Android(安卓)图片加边框
  7. Android将图片转为字节流存储在SharedPreferences
  8. Android封装保存图片工具类ImageUtils
  9. Android播放循环播放本地图片

随机推荐

  1. android解析xml文件的方式之SAX方式
  2. 如何跳过Nexus 7二代的开机设置
  3. Android开发--身高体重指数(BIM)计算--访问
  4. [置顶] Android(安卓)通知栏Notification
  5. Android(安卓)Studio自定义组合控件
  6. Android的广播Receiver动态注册和静态注
  7. android异步UI刷新实例总结
  8. Android动画特效
  9. 谈谈Android里的Context的使用!!!
  10. Android实现IOS相机滑动控件