好久没写博客了,一方面是因为最近找了家实习单位,很累基本上下班后就没有打不起精神去学习,另一方面我自己觉得写博客确实有点耗时间,趁着周六周日想花点时间研究下fresco,picass,Glide等框架,但是如何哪种框架,Bitmap总是基础,花了一上午的时间整理了下bitmap压缩的工具类,这里分享一下
package com.example.liujian.bitmapdemo;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.util.Log;
import android.view.WindowManager;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
/**
* create by liujian 2015/11/10
* 图片压缩工具类
*/
public class ImageResizerUtils {
private static final String TAG = ImageResizerUtils.class.getSimpleName();
private Context context;
private WindowManager mWindowManager;
public ImageResizerUtils(Context context) {
this.context=context;
}
/**
* 放大缩小图片,指定宽高
* @param bitmap
* @param w
* @param h
* @return
*/
public Bitmap resizeBitmap(Bitmap bitmap, int w, int h) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Matrix matrix = new Matrix();
float scaleWidht = ((float) w / width);
float scaleHeight = ((float) h / height);
matrix.postScale(scaleWidht, scaleHeight);
Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height,
matrix, true);
if (!bitmap.isRecycled()) {
bitmap.recycle();
}
return newbmp;
}
/**
* Matrix类实现图片放大缩小,指定宽,宽高比例跟原图一致
* @param bitmap
* @param newWidth
* @return
*/
public Bitmap resizeBitmap(Bitmap bitmap, int newWidth) {
if (bitmap == null)
return null;
int w = bitmap.getWidth();
int h = bitmap.getHeight();
float temp = ((float) h) / ((float) w);
int newHeight = (int) (newWidth * temp);
float scaleWidth = ((float) newWidth) / w;
float scaleHeight = ((float) newHeight) / h;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix,
true);
if (!bitmap.isRecycled()) {
bitmap.recycle();
}
return resizedBitmap;
}
/**
* 压缩成屏幕能够接受的大小
* @param is
* @return
*/
public Bitmap resizeBitmap(FileInputStream is) throws IOException {
return resizeBitmap(is.getFD());
}
public Bitmap resizeBitmap(FileInputStream is,int reqWidth,int reqHeight) throws IOException {
return resizeBitmap(is.getFD(),reqWidth,reqHeight);
}
public Bitmap resizeBitmap(FileDescriptor fd) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFileDescriptor(fd, null, options);
options.inSampleSize = calculateInWindowSize(options);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFileDescriptor(fd, null, options);
}
/**
* 压缩方法对FileInputStream的缩放存在问题,原因是FileInputStream是一种有序的
* 文件流,而两次decodeStream调用影响了文件流的位置属性,导致第二次BitmapFactory.
* decodeStream时得到是null。我们可以通过文件流来得到它所对应的文件描述符,
* @param fd:FileDescriptor df = is.getFD();
* @param reqWidth:所需图片宽(像素)
* @param reqHeight:所需图片高(像素)
* @return
*/
public Bitmap resizeBitmap(FileDescriptor fd,int reqWidth, int reqHeight) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFileDescriptor(fd, null, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFileDescriptor(fd, null, options);
}
/**
*
* @param res:Resources对象
* @param resId:资源文件id
* @return
*/
public Bitmap resizeBitmap(Resources res, int resId) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;// 不去解析真正的位图,只是去获取这个文件的头文件信息
BitmapFactory.decodeResource(res, resId, options);
// 得到压缩的缩放比
options.inSampleSize = calculateInWindowSize(options);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
/**
*
* @param res:Resources对象
* @param resId:资源文件id
* @param reqWidth:缩放的目标Bitmao的宽度
* @param reqHeight:缩放的目标Bitmap的高度
* @return
*/
public Bitmap resizeBitmap(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 path
* @param reqWidth
* @param reqHeight
* @return
*/
public Bitmap resizeBitmap(String path,int reqWidth,int reqHeight){
BitmapFactory.Options opts=new BitmapFactory.Options();//解析位图的附加条件
opts.inJustDecodeBounds=true;
BitmapFactory.decodeFile(path,opts);
opts.inSampleSize=calculateInSampleSize(opts,reqWidth,reqHeight);
opts.inJustDecodeBounds=false;
return BitmapFactory.decodeFile(path,opts);
}
/**
* 根据路径压缩成屏幕可以接受的大小
* @param path
* @return
*/
public Bitmap resizeBitmap(String path){
BitmapFactory.Options opts=new BitmapFactory.Options();//解析位图的附加条件
opts.inJustDecodeBounds=true;
BitmapFactory.decodeFile(path,opts);
opts.inSampleSize=calculateInWindowSize(opts);
opts.inJustDecodeBounds=false;
return BitmapFactory.decodeFile(path,opts);
}
/**
* 根据需要的图片宽高(px像素)来压缩 返回缩放比 缩放比大于1时,比如为2,
* 压缩后的图片其宽高均为原图大小的1/2,其所占的内存大小也为原图的1/4
* @param options
* @param reqWidth:压缩的目标宽
* @param reqHeight:压缩的目标高
* @return 返回缩放比
*/
private int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
if (reqWidth <= 0 || reqHeight <= 0) {
return 1;
}
// 得到图片的宽高
final int height = options.outHeight;
final int width = options.outWidth;
Log.d(TAG, "origin, w= " + width + " h=" + height);
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
Log.d(TAG, "sampleSize:" + inSampleSize);
return inSampleSize;
}
/**
* 压缩成屏幕能够接受的大小的缩放比
* @param options
* @return
*/
private int calculateInWindowSize(BitmapFactory.Options options){
//得到屏幕宽高
if(mWindowManager==null){
mWindowManager=((Activity)context).getWindowManager();
}
int windowWidth=mWindowManager.getDefaultDisplay().getWidth();
int windowHeight=mWindowManager.getDefaultDisplay().getHeight();
int bitmapWidth=options.outWidth;
int bitmapHeight=options.outHeight;
int dx=bitmapWidth/windowWidth;
int dy=bitmapHeight/windowHeight;
int scale=1;
if(dx>dy&&dy>1){
scale=dx;
}
if(dy>dx&&dy>1){
scale=dy;
}
return scale;
}
}