一个好用的android图片压缩工具类


<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">用了很久图片压缩,之前人们一直使用google的官方图片压缩方法</span>

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)效果:

<pre name="code" class="java"><span style="font-family: Arial, Helvetica, sans-serif;">/**</span>

* 计算压缩比例值(改进版 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即清空baos
			options -= 10;// 每次都减少10
			image.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;
}
时间: 2024-10-20 15:40:57

一个好用的android图片压缩工具类的相关文章

Android图片操作工具类

package com.aliyun.oss.ossdemo; import android.app.Activity; import android.app.AlertDialog; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Handler; import android.os.Looper; import android.os.Message; import

功能这么齐全的图片压缩类,还有谁?

效果图: 压缩日志 com.pengkv.moon I/--->: 原尺寸:1215*1080 com.pengkv.moon I/--->: 最终压缩比例:3倍/新尺寸:405*360 工具特点 * 可以解析单张图片 * 可以解析多张图片 * 处理了压缩过程中OOM * 处理了部分手机照片旋转问题 * 压缩后存储在缓存中,并可以清理 * 压缩后返回缓存路径,方便上传 * 可以从缓存路径读取出Bitmap,方便展示 * 封装在2个类里,方便调用 使用方法 ImageCompressUtil.c

毕加索的艺术——Picasso,一个强大的Android图片下载缓存库,OkHttpUtils的使用,二次封装PicassoUtils实现微信精选

毕加索的艺术--Picasso,一个强大的Android图片下载缓存库,OkHttpUtils的使用,二次封装PicassoUtils实现微信精选 官网: http://square.github.io/picasso/ 我们在上篇OkHttp的时候说过这个Picasso,学名毕加索,是Square公司开源的一个Android图形缓存库,而且使用起来也是非常的简单,只要一行代码就轻松搞定了,你会问,为什么不介绍一下Glide?其实Glide我有时间也是会介绍的,刚好上篇我们用到了Picasso,

一起写一个Android图片加载框架

本文会从内部原理到具体实现来详细介绍如何开发一个简洁而实用的Android图片加载缓存框架,并在内存占用与加载图片所需时间这两个方面与主流图片加载框架之一Universal Image Loader做出比较,来帮助我们量化这个框架的性能.通过开发这个框架,我们可以进一步深入了解Android中的Bitmap操作.LruCache.LruDiskCache,让我们以后与Bitmap打交道能够更加得心应手.若对Bitmap的大小计算及inSampleSize计算还不太熟悉,请参考这里:高效加载Bit

Android Handler 异步消息处理机制的妙用 创建强大的图片载入类

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38476887 ,本文出自[张鸿洋的博客] 近期创建了一个群.方便大家交流,群号:55032675 上一篇博客介绍了Android异步消息处理机制.假设你还不了解,能够看:Android 异步消息处理机制 让你深入理解 Looper.Handler.Message三者关系 . 那篇博客的最后,提出能够把异步消息处理机制不仅仅是在MainActivity中更新UI.能够用到别的地方

Android实用工具类-GrallyAndPhotoUtils图片处理工具

目录 目录 概述 前言 拍照 创建存储拍照图片的文件 调用系统拍照程序 读取相册图片 获取返回URI中的图片路径 统一的回调处理 图片缩略图加载 加载流程 计算缩略图比例 缩略图加载 源码 图片加载结果 示例GIF 概述 此类是用于简便调用系统拍照及打开相册选择图片.通用于多种机型.(亲测魅族MX4,三星note 2,三星note 3) 前言 在执行拍照和打开相册之前,我们需要注意一下. 由于Android开放的系统,很多手机厂商是定制自己的系统的,那么就存在一个问题.尽管大部分时候拍照或者打开

Fresco介绍 - 一个新的android图片加载库

在Android设备上面,快速高效的显示图片是极为重要的.过去的几年里,我们在如何高效的存储图像这方面遇到了很多问题.图片太大,但是手机的内存却很小.每一个像素的R.G.B和alpha通道总共要占用4byte的空间.如果手机的屏幕是480*800,那么一张屏幕大小的图片就要占用1.5M的内存.手机的内存通常很小,特别是Android设备还要给各个应用分配内存.在某些设备上,分给Facebook App的内存仅仅有16MB.一张图片就要占据其内存的十分之一. 当你的App内存溢出会发生什么呢?它当

android开发——camera类拍照指定图片大小

android拍照开发 android开发实现拍照功能主要有两种方法: 直接调用系统照相机API实现拍照,拍完后,图片会保存在相册中,返回保存照片的路径,从而获取图片. 自己写SurfaceView调用camera来实现拍照,该方法触发一个回调,参数中包含一个图片字节数组,从而获取图片. 问题 当我们自定义相机时,需求需要指定拍照图片大小,然而不同手机会默认返回不同分辨率照片.所以需要对camera进行参数设置.通过设置setPictureSize,代码: // 获得相机参数 Camera.Pa

Android 中图可以用到的图片处理类 BitmapUtils

Android在实际开发中很多时候都要对图片进行一定的处理,这里总结的BitmapUtils 类包括一下几个功能: 1.Android图片倒影, 2.Android图片模糊处理, 3.Android图片圆角处理, 4.图片沿着y轴旋转一定角度, 5.Android给图片添加边框. 接下来就直接上代码了,代码中有一定的解释.直接哪来用就可以了. /* * @Title: BitmapUtils.java * @Copyright: Corporation. Ltd. Copyright 1998-