Android 图片压缩
2017-11-29 本文已影响119人
Android师哥
night_rain.png
Android中图片压缩一般有两种方式,一种是通过改变图片的尺寸来改变图片的大小,另一种是通过改变图片像素的质量来改变图片的大小。第一种方式会直接改变Bitmap大小,也就是图片的宽高尺寸改变。第二种方式是改变了图片中像素的质量,本身的尺寸没有变化,但是体积确发生了变化!
- 第一步
将一个本地图片转化为Bitmap(要注意OOM)
/**
* 将本地路径转化为Bitmap
*
* @param path 本地路径
* @return 返回本地资源的Bitmap
*/
private Bitmap loadFile(String path) {
File mFile = new File(path);
Bitmap mBitmap = null;
//判读文件是否存在
if (mFile.exists()) {
BitmapFactory.Options mOptions = new BitmapFactory.Options();
//设置只加载尺寸资源
mOptions.inJustDecodeBounds = true;
//设置资源
BitmapFactory.decodeFile(path, mOptions);
//图片加载缩方处理
coundScale(mOptions);
//设置加载资源模式
mOptions.inJustDecodeBounds = false;
//设置资源
mBitmap = BitmapFactory.decodeFile(path, mOptions);
}
return mBitmap;
}
/**
* 计算缩放比例,防止OOM
*
* @param opeions BitmapFactory.Options
*/
private void coundScale(BitmapFactory.Options opeions) {
if (opeions != null) {
//原图的尺寸
int orginalWidht = opeions.outWidth;
int orginalHieght = opeions.outHeight;
//如果图片尺寸大于一定尺寸的时候进行缩放
if (orginalWidht > 1080 || orginalHieght > 1920) {
//缩小倍数
int scale = 1;
if (orginalWidht > orginalHieght) {
//长图片的时候(以宽度为基准缩小)
scale = orginalWidht / 1080;
} else if (orginalWidht < orginalHieght) {
//高图的时候(以高度为基准缩小)
scale = orginalHieght / 1920;
} else {
//正方形图的时候(以宽度为基准缩小)
scale = orginalWidht / 1080;
}
Log.i(TAG, "coundScale: " + scale);
opeions.inSampleSize = scale;
}
}
}
- 第二步
改变图片的尺寸
/**
* 进行图片尺寸裁剪
*
* @param loadBitmap 本地图片资源
* @return 尺寸处理后的资源
*/
private Bitmap cutFile(Bitmap loadBitmap) {
Bitmap mCutBitmap = null;
if (loadBitmap != null) {
//获取经过第一次处理后图片的尺寸;
int mLoadBitmapWidth = loadBitmap.getWidth();
int mLoadBitmapHeight = loadBitmap.getHeight();
float scaleX = 0;
float scaleY = 0;
//图片的宽高比例
float picScale = (float) mLoadBitmapWidth / mLoadBitmapHeight;
//计算压缩尺寸比(无论图片大小,直接规定尺寸)
if (mLoadBitmapWidth > mLoadBitmapHeight) {
//长图片的时候(宽度缩放到1080,高度安装原图的宽高比缩放尺寸)
scaleX = 1080.0F / mLoadBitmapWidth;
scaleY = 1080.0F / picScale / mLoadBitmapHeight;
} else if (mLoadBitmapWidth < mLoadBitmapHeight) {
//高图的时候
scaleX = 1080.0F / mLoadBitmapWidth;
scaleY = 1920.0F / mLoadBitmapHeight;
} else {
//正方形图的时候(按照宽度为基准缩放)
scaleX = 1080.0F / mLoadBitmapWidth;
scaleY = scaleX;
}
//创建一个矩阵
Matrix mMatrix = new Matrix();
//设置缩放比例
mMatrix.postScale(scaleX, scaleY);
//生成新的Bitmap
mCutBitmap = Bitmap.createBitmap(loadBitmap, 0, 0, mLoadBitmapWidth, mLoadBitmapHeight, mMatrix, false);
}
return mCutBitmap;
}
- 第三步
改变图片的质量
/**
* 质量压缩
*
* @param mBitmap 处理尺寸后的资源
* @return 压缩结束后的文件
*/
private File qualtiy(Bitmap mBitmap) {
File mFile = null;
if (mBitmap != null) {
//设置压缩后图片不超过100KB
int maxKB = 100;
//创建一个缓存区
ByteArrayOutputStream mByteArrayOutputStream = new ByteArrayOutputStream();
//默认压缩质量(不压缩)
int options = 100;
//压缩后的大小
int endKB = 0;
do {
//清空缓存区
mByteArrayOutputStream.reset();
//将数据写入缓存区
mBitmap.compress(Bitmap.CompressFormat.JPEG, options, mByteArrayOutputStream);
//降低质量
options -= 5;
//重新计算缓存区数据大小
endKB = mByteArrayOutputStream.toByteArray().length;
//如果压缩系数小于0的时候直接跳出循环
if (options <= 0) {
break;
}
//判断当前资源大小是否大于期望大小
} while (endKB / 1024 > maxKB);
//创建一个输入流
FileOutputStream mFileOutputStream = null;
BufferedOutputStream mBufferedOutputStream = null;
//创建一个空文件
mFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/manageEnd.jpg");
try {
mFileOutputStream = new FileOutputStream(mFile);
mBufferedOutputStream = new BufferedOutputStream(mFileOutputStream);
//将压缩后的数据写入都空文件中
mBufferedOutputStream.write(mByteArrayOutputStream.toByteArray());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (mByteArrayOutputStream != null && mBufferedOutputStream != null && mFileOutputStream != null) {
//关闭流
mByteArrayOutputStream.flush();
mBufferedOutputStream.flush();
mFileOutputStream.close();
mBufferedOutputStream.close();
mByteArrayOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
return mFile;
}
简单的压缩图片就这些,代码中基本的注释都有,如果文章中有什么不合适或者有好想法的书友可以在评论中提出,我会尽快修改!谢谢~~
注意:
记得添加文件读写权限
GitHub主页