android系统在运行的过程中如果图片过大会导致应用所占内存快速增加致使内存溢出(OOM)所有在显示图片的过程中需要对较大图片进行一定的压缩处理,
压缩方式有两种,一是对图片的质量进行压缩,而是对图片的宽高进行压缩。
具体实现的时候会根据需求来设计不同的实现函数,下面列举几个可能用到的
1、
/**
* 质量压缩法1:可以指定压缩的比例
*
* @param image 要压缩的图片
* @param filepath 文件保存路径
* @return
*/
public static Bitmap compressImage(Bitmap image, String filepath) {
//不设置压缩比默认压缩%50,经过测试%50图片大小会减小3/4.如100K的文件大概会压缩到25K
return compressImage(image, filepath, 50);
}
/**
* 质量压缩法1:可以指定压缩的比例
*
* @param image 要压缩的图片
* @param filepath 文件保存路径
* @param quality 压缩的质量比
* @return
*/
public static Bitmap compressImage(Bitmap image, String filepath, int quality) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
image.compress(Bitmap.CompressFormat.JPEG, quality, baos);
//压缩好后写入文件中
FileOutputStream fos = new FileOutputStream(filepath);
fos.write(baos.toByteArray());
fos.flush();
fos.close();
return image;//image大小没有变,只是存储的文件变小了
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
这里做一下解释,
1、经过测试%50图片大小会减小3/4.如100K的文件大概会压缩到25K。
2、compressImage(Bitmap image, String filepath, int quality),的第一个参数image如果大小为100K.,return image的大小也是100K,没有减小,但是保存的文件大小被压缩了。因为
image.compress(Bitmap.CompressFormat.JPEG, quality, baos);
将被压缩的内容保存在boos变量中,image大小不变。如果要让返回的image也是被压缩过的图片。可以在返回之前更新image为压缩后的内容。
//把压缩后的数据baos存放到ByteArrayInputStream中
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
image.recycle();
image = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
return image;
2、设置输出图片的被压缩后的最大大小。
public static Bitmap compressImage2(Bitmap image, String filepath) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
int options = 90;
while (baos.toByteArray().length / 1024 > 200) { // 循环判断如果压缩后图片是否大于200kb,大于继续压缩
baos.reset(); // 重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中
options -= 10;// 每次都减少10
}
try {
FileOutputStream fos = new FileOutputStream(filepath);
fos.write(baos.toByteArray());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
return image;
}
3、压缩图片的宽高
public static Bitmap ResizeBitmap(Bitmap bitmap, int newWidth) {//拍照的图片太大,设置格式大小
//获取原来图片的宽高
int width = bitmap.getWidth();
int height = bitmap.getHeight();
//计算原来图片的高宽之比
float temp = ((float) height) / ((float) width);
//根据传入的新图片的宽度计算新图片的高度
int newHeight = (int) ((newWidth) * temp);
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
//Bitmap 通过matrix 矩阵变换生成新的Bitmap
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
bitmap.recycle();
return resizedBitmap;
}