用了很久图片压缩,之前人们一直使用google的官方图片压缩方法

final BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeResource(res, resId, options);options.inSampleSize = calculateInSampleSize(options, reqWidth,reqHeight);options.inJustDecodeBounds = false;return BitmapFactory.decodeResource(res, resId, options);


public static int calculateInSampleSize(            BitmapFactory.Options options, int reqWidth, int reqHeight) {    // Raw height and width of image    final int height = options.outHeight;    final int width = options.outWidth;    int inSampleSize = 1;    if (height > reqHeight || width > reqWidth) {        final int halfHeight = height / 2;        final int halfWidth = width / 2;        // Calculate the largest inSampleSize value that is a power of 2 and keeps both        // height and width larger than the requested height and width.        while ((halfHeight / inSampleSize) > reqHeight                && (halfWidth / inSampleSize) > reqWidth) {            inSampleSize *= 2;        }    }    return inSampleSize;}

代码来自google 

http://developer.android.com/training/displaying-bitmaps/load-bitmap.html


仔细看calucelateInSamplesize方法,该算法返回的是一种压缩比例,仔细一看他的计算过程,你会发现,inSampleSize的变化过程是2-4-8,,而真正进入wile循环时,宽高就已经被看成是小了一半来计算的了,所以,上面那个网站说12M能压缩到0.75M,就是因为差距太大,如果安卓手机内部压缩自己的图片(大概是2M压缩到100K),所以此时,这个方法就适用于android编码压缩了。

所以鄙人针对于android编码时压缩,在此对它进行了优化,优化后代码如下:

运行:   culculateInSampleSize(bm,200,300)效果:

/**
* 计算压缩比例值(改进版 by touch_ping)

* 原版2>4>8...倍压缩
* 当前2>3>4...倍压缩

* @param options
*            解析图片的配置信息
* @param reqWidth
*            所需图片压缩尺寸最小宽度
* @param reqHeight
*            所需图片压缩尺寸最小高度
* @return
*/
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {

final int picheight = options.outHeight;
final int picwidth = options.outWidth;
Log.i("test", "原尺寸:" +  picwidth + "*" +picheight);

int targetheight = picheight;
int targetwidth = picwidth;
int inSampleSize = 1;

if (targetheight > reqHeight || targetwidth > reqWidth) {
while (targetheight  >= reqHeight
&& targetwidth>= reqWidth) {
Log.i("test","压缩:" +inSampleSize + "倍");
inSampleSize += 1;
targetheight = picheight/inSampleSize;
targetwidth = picwidth/inSampleSize;
}
}

Log.i("test","最终压缩比例:" +inSampleSize + "倍");
Log.i("test", "新尺寸:" +  targetwidth + "*" +targetheight);
return inSampleSize;
}
   
压缩效果如下:


文件大小从1.12M变成81.75k



最终附上完整压缩工具类:

package com.example.mqtest;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import android.content.res.Resources;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.util.Log;/** * 图片压缩工具类 * @author touch_ping * 2015-1-5 下午1:29:59 */public class BitmapCompressor {/** * 质量压缩 * @author ping 2015-1-5 下午1:29:58 * @param image * @param maxkb * @return */public static Bitmap compressBitmap(Bitmap image,int maxkb) {//L.showlog("压缩图片");ByteArrayOutputStream baos = new ByteArrayOutputStream();image.compress(Bitmap.CompressFormat.JPEG, 50, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中int options = 100;//Log.i("test","原始大小" + baos.toByteArray().length);while (baos.toByteArray().length / 1024 > maxkb) { // 循环判断如果压缩后图片是否大于(maxkb)50kb,大于继续压缩//Log.i("test","压缩一次!");baos.reset();// 重置baos即清空baosoptions -= 10;// 每次都减少10image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中}//Log.i("test","压缩后大小" + baos.toByteArray().length);ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片return bitmap;}/** * http://developer.android.com/training/displaying-bitmaps/load-bitmap.html * 官网:获取压缩后的图片 *  * @param res * @param resId * @param reqWidth *            所需图片压缩尺寸最小宽度 * @param reqHeight *            所需图片压缩尺寸最小高度 * @return */public static Bitmap decodeSampledBitmapFromResource(Resources res,int resId, int reqWidth, int reqHeight) {final BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeResource(res, resId, options);options.inSampleSize = calculateInSampleSize(options, reqWidth,reqHeight);options.inJustDecodeBounds = false;return BitmapFactory.decodeResource(res, resId, options);}/** * 官网:获取压缩后的图片 *  * @param res * @param resId * @param reqWidth *            所需图片压缩尺寸最小宽度 * @param reqHeight *            所需图片压缩尺寸最小高度 * @return */public static Bitmap decodeSampledBitmapFromFile(String filepath,int reqWidth, int reqHeight) {final BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeFile(filepath, options);options.inSampleSize = calculateInSampleSize(options, reqWidth,reqHeight);options.inJustDecodeBounds = false;return BitmapFactory.decodeFile(filepath, options);}public static Bitmap decodeSampledBitmapFromBitmap(Bitmap bitmap,int reqWidth, int reqHeight) {ByteArrayOutputStream baos = new ByteArrayOutputStream();bitmap.compress(Bitmap.CompressFormat.PNG, 90, baos);byte[] data = baos.toByteArray();final BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeByteArray(data, 0, data.length, options);options.inSampleSize = calculateInSampleSize(options, reqWidth,reqHeight);options.inJustDecodeBounds = false;return BitmapFactory.decodeByteArray(data, 0, data.length, options);}/** * 计算压缩比例值(改进版 by touch_ping) *  * 原版2>4>8...倍压缩 * 当前2>3>4...倍压缩 *  * @param options *            解析图片的配置信息 * @param reqWidth *            所需图片压缩尺寸最小宽度O * @param reqHeight *            所需图片压缩尺寸最小高度 * @return */public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth, int reqHeight) {final int picheight = options.outHeight;final int picwidth = options.outWidth;Log.i("test", "原尺寸:" +  picwidth + "*" +picheight);int targetheight = picheight;int targetwidth = picwidth;int inSampleSize = 1;if (targetheight > reqHeight || targetwidth > reqWidth) {while (targetheight  >= reqHeight&& targetwidth>= reqWidth) {Log.i("test","压缩:" +inSampleSize + "倍");inSampleSize += 1;targetheight = picheight/inSampleSize;targetwidth = picwidth/inSampleSize;}}Log.i("test","最终压缩比例:" +inSampleSize + "倍");Log.i("test", "新尺寸:" +  targetwidth + "*" +targetheight);return inSampleSize;}}








public static int calculateInSampleSize(            BitmapFactory.Options options, int reqWidth, int reqHeight) {    // Raw height and width of image    final int height = options.outHeight;    final int width = options.outWidth;    int inSampleSize = 1;    if (height > reqHeight || width > reqWidth) {        final int halfHeight = height / 2;        final int halfWidth = width / 2;        // Calculate the largest inSampleSize value that is a power of 2 and keeps both        // height and width larger than the requested height and width.        while ((halfHeight / inSampleSize) > reqHeight                && (halfWidth / inSampleSize) > reqWidth) {            inSampleSize *= 2;        }    }    return inSampleSize;}

更多相关文章

  1. android 下载图片保存在sdcard并显示可拖动缩放
  2. android保存Bitmap图片到指定文件夹示例
  3. Android 图片水平显示 类Gallery效果
  4. android在grid组件中加入添加删除图片按钮
  5. java|android加载src路径下面的图片文件
  6. android中得到颜色,图片资源的方式
  7. 背景圆角以及图片圆角处理
  8. android 拍照,图片裁剪,选择图片

随机推荐

  1. Android实现页面跳转
  2. AndroidManifest中activity属性设置大全
  3. android:HttpClient请求(get、post)
  4. Android中获得SD卡中的值
  5. Android(安卓)APP无法接收开机广播
  6. OpenWrt上运行Android(安卓)OS
  7. android网站汇总
  8. Android(安卓)开发判断用户是否安装微信
  9. Android(安卓)EditText 自动获取焦点,并弹
  10. android之datepicker控件用法