最近处理图片遇到一些问题,网上的图片压缩很多都是使用bitmap.compress(),但是发现还是有OOM
原先的代码,有问题的:
public String cutPictureQuality(Bitmap bitmap, String fname) {
String fileName = fname + ".jpg";// UUID.randomUUID().toString().replace("-","") + ".jpg";
String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + context.getPackageName() + "/UserIcon";
//Environment.getExternalStorageDirectory() + File.separator + savePackage;
// 判断文件夹存在
File file = new File(filePath);
if (file != null && !file.exists()) {
file.mkdirs();
}
try {
// 第一次压缩
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
FileOutputStream fos = new FileOutputStream(new File(filePath, fileName));
int options = 100;
// 如果大于150kb则再次压缩,最多压缩三次
while (baos.toByteArray().length / 1024 > 150 && options != 10) {
// 清空baos
baos.reset();
// 这里压缩options%,把压缩后的数据存放到baos中
bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);
options -= 30;
}
fos.write(baos.toByteArray());
fos.close();
baos.close();
} catch (Exception e) {
}
return filePath + File.separator + fileName;
}
以上使用compress压缩,得到的结果加载时还是会发生oom,网上找了资料说compress压缩的是图片保存到内存的大小,
加载的时候,获取的图片大小还是不变的
现在采用的压缩方式是
public Bitmap cutPictureSize(String filePath, int reqWidth, int reqHeight) {
Display mDisplay = ((Activity) context).getWindowManager().getDefaultDisplay();
// int width = mDisplay.getWidth();
// int height = mDisplay.getHeight();
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;//只是获取图片边框,不加载图片
BitmapFactory.decodeFile(filePath, options);
options.inSampleSize = 4;//设置采样比例 这里是四行取一行,4列取1列,得到的大小是原来的1/16
options.inJustDecodeBounds = false; //然后设置加载图片
return BitmapFactory.decodeFile(filePath, options);
}
加载的思路基本是这样,也可以根据图片的width和height来计算inSamplesize
private int cutBySize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
基本就是这样,因为刚开始没有了解过Glide等第三方图片加载框架,所以遇到很多坑。后面的项目会采用第三方加载,有同样问题的可以去了解下