* 图片质量压缩
* @param image
* @return
*/
public static Bitmap compressImage(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
int options = 90;
while ( baos.toByteArray().length / 1024>100) { //循环判断如果压缩后图片是否大于100kb,大于继续压缩
baos.reset();//重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中
options -= 10;//每次都减少10
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
return bitmap;
}
/**
* 根据View(主要是ImageView)的宽和高来获取图片的缩略图
*
* @param path
* @param viewWidth
* @param viewHeight
* @return
*/
public static Bitmap decodeThumbBitmapForFile(String path, int viewWidth,
int viewHeight) {
BitmapFactory.Options options = new BitmapFactory.Options();
// 设置为true,表示解析Bitmap对象,该对象不占内存
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// 设置缩放比例
options.inSampleSize = computeScale(options, viewWidth, viewHeight);
options.inPreferredConfig = Config.RGB_565;
// 设置为false,解析Bitmap对象加入到内存中
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
}
/**
* 根据View(主要是ImageView)的宽和高来计算Bitmap缩放比例。默认不缩放
*
* @param options
* @param width
* @param height
*/
public static int computeScale(BitmapFactory.Options options,
int viewWidth, int viewHeight) {
int inSampleSize = 1;
if (viewWidth == 0 || viewHeight == 0) {
return inSampleSize;
}
int bitmapWidth = options.outWidth;
int bitmapHeight = options.outHeight;
// 假如Bitmap的宽度或高度大于我们设定图片的View的宽高,则计算缩放比例
if (bitmapWidth > viewWidth || bitmapHeight > viewWidth) {
int widthScale = Math
.round((float) bitmapWidth / (float) viewWidth);
int heightScale = Math.round((float) bitmapHeight
/ (float) viewWidth);
// 为了保证图片不缩放变形,我们取宽高比例最小的那个
//inSampleSize = widthScale < heightScale ? widthScale : heightScale;
inSampleSize = ( widthScale+heightScale)/2;
}
return inSampleSize;
}
********************************************控制内存的类******************************************************
*************手机图片浏览器中用到的*************************************
/**
* 防止溢出
*
*/
public class BitmapCache {
private static BitmapCache cache = new BitmapCache();
// 用于Chche内容的存储
private static Hashtable<String, BtimapRef> bitmapRefs = new Hashtable<String, BtimapRef>();
// 垃圾Reference的队列(所引用的对象已经被回收,则将该引用存入队列中)
private static ReferenceQueue<Bitmap> refq = new ReferenceQueue<Bitmap>();
/**
* 继承SoftReference,使得每一个实例都具有可识别的标识。
*/
private static class BtimapRef extends SoftReference<Bitmap> {
private String _key = "";
public BtimapRef(Bitmap bmp, ReferenceQueue<Bitmap> q, String key) {
super(bmp, q);
_key = key;
}
}
private BitmapCache() {
bitmapRefs = new Hashtable<String, BtimapRef>();
refq = new ReferenceQueue<Bitmap>();
}
/**
* 取得缓存器实例
*/
public static BitmapCache getInstance() {
if (cache == null) {
cache = new BitmapCache();
}
return cache;
}
/**
* 以软引用的方式对一个Bitmap对象的实例进行引用并保存该引用
*/
private static void addCacheBitmap(Bitmap bmp, String key) {
cleanCache();// 清除垃圾引用
BtimapRef ref = new BtimapRef(bmp, refq, key);
bitmapRefs.put(key, ref);
}
/**
* 依据所指定的文件名获取图片(不会出现内存溢出问题)
*/
public static Bitmap getBitmap(String path, int viewWidth, int viewHeight) {
Bitmap bitmapImage = null;
// 缓存中是否有该Bitmap实例的软引用,如果有,从软引用中取得。
if (bitmapRefs.containsKey(path)) {
BtimapRef ref = (BtimapRef) bitmapRefs.get(path);
bitmapImage = (Bitmap) ref.get();
}
// 如果没有软引用,或者从软引用中得到的实例是null,重新构建一个实例,
// 并保存对这个新建实例的软引用
if (bitmapImage == null) {
BitmapFactory.Options options = new BitmapFactory.Options();
// 设置为true,表示解析Bitmap对象,该对象不占内存
options.inJustDecodeBounds = true;
bitmapImage = BitmapFactory.decodeFile(path, options);
// 设置缩放比例
options.inSampleSize = ImageUtil.computeScale(options, viewWidth,
viewHeight);
// 设置为false,解析Bitmap对象加入到内存中
options.inJustDecodeBounds = false;
options.inPreferredConfig = Config.RGB_565;
bitmapImage = BitmapFactory.decodeFile(path, options);
addCacheBitmap(bitmapImage, path);
}
return bitmapImage;
}
private static void cleanCache() {
BtimapRef ref = null;
while ((ref = (BtimapRef) refq.poll()) != null) {
bitmapRefs.remove(ref._key);
}
}
// 清除Cache内的全部内容
public static void clearCache() {
cleanCache();
bitmapRefs.clear();
System.gc();
System.runFinalization();
}
}