1,通过BitmapFactory.Options加载图片
由于加载图片导致OOM是很常见的情况。导致OOM的原因之一就是所加载的图片太大。如果我们不对原图做任何设置,就极其容易导致OOM。通过BitmapFactory.Options的核心思想就是加载我们所需尺寸的图片即可。很多时候,我们所需要的图片尺寸没有图片的原始尺寸那么大。
通过BitmapFactory.Options来缩放图片,主要用到了它的inSampleSize参数,即采样率。当inSampleSize为1时,采样后的图片与原图的大小相同。当inSampleSize为2时,采样后的图片的宽和高均为原图的1/2,像素数为原来的1/4.
加载图片的步骤:
- 将BitmapFactory.Options的inJustDecodeBounds参数设为true并加载图片。
- 从BitmapFactory.Options取出原始图片的宽高信息,对应为outWidth和outHeight参数。
- 根据所需要的图片大小计算采样率inSampleSize。
- 将BitmapFactory.Options的inJustDecodeBounds参数设为false并重新加载图片。
/**
* 根据Image的大小来加载图片
* @param res
* @param resid
* @param reqWidth
* @param reqHeight
* @return
*/
public static Bitmap decodeBitmapFromResource(Resources res,int resid,int reqWidth,int reqHeight){
BitmapFactory.Options options=new BitmapFactory.Options();
/**
* 设置为true后,BitmapFactory并不会正真的去加载图片。
*
*/
options.inJustDecodeBounds=true;
BitmapFactory.decodeResource(res,resid,options);
/**
* 得到原始图片的宽和高
*/
int height=options.outHeight;
int width=options.outWidth;
/**
* 根据需要的宽和高以及原图的宽和高,计算采样率。
*
*/
int scaleFctor=Math.max(width/reqWidth,height/reqHeight);
/**
* 将计算出的采样率赋值给options.inSampleSize
*/
options.inSampleSize=scaleFctor;
/**
* 设为false,则正真开始加载图片。
*/
options.inJustDecodeBounds=false;
return BitmapFactory.decodeResource(res, resid, options);
}
除了这种最常见的方式,使用下面的代码也可以有效地避免OOM,亲测。
public Bitmap readBitmap(Context context, int resId) {
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inPreferredConfig = Bitmap.Config.RGB_565;
opts.inPurgeable = true;
opts.inInputShareable = true;
InputStream is = context.getResources().openRawResource(resId);
return BitmapFactory.decodeStream(is, null, opts);
}
但是,这种方式是以牺牲图片的质量作为代价的。opts.inPreferredConfig的默认值是Bitmap.Config.ARGB_8888。除此之外,这里面有两个API已经过时。
2,将Bitmap保存到本地
/**
* 将Bitmap保存到本地
* 并且返回路径
* @param canvasBitmap
*/
public static String saveBitmap(Bitmap canvasBitmap){
try{
File file=new File(Environment.getExternalStorageDirectory(),"图片");
if(!file.exists()){
file.mkdir();
}
File file2=new File(file,System.currentTimeMillis()+".jpg");
file2.createNewFile();
String path=file2.getAbsolutePath();
FileOutputStream fileOutputStream=new FileOutputStream(file2);
/**
* 第一个参数表示压缩的格式,有三个值可以选择:JPEG,PNG,WEBP
* 第二个参数表示压缩的质量,取值为0~100。其中100是压缩后图片质量做好的。
* 最后一个参数是输出流,即将Bitmap保存的位置。
*/
canvasBitmap.compress(Bitmap.CompressFormat.JPEG,100,fileOutputStream);
fileOutputStream.close();
return path;
}
catch (Exception e){
// Toast.makeText(this,e.getMessage(),Toast.LENGTH_SHORT).show();
Log.i("liang",e.getMessage());
return null;
}
}
3,Bitmap的缩放
/**
* 对Bitmap进行缩放
* @param bitmap
* @param reqWidth
* @param reqHeight
* @return
*/
public static Bitmap shrink (Bitmap bitmap,float reqWidth,float reqHeight) {
Matrix matrix = new Matrix();
matrix.postScale(reqWidth,reqHeight); //长和宽放大缩小的比例
Bitmap resizeBmp = Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
return resizeBmp;
}