安卓开发之Bitmap(二)

时间:2022-08-14 22:43:05

1,通过BitmapFactory.Options加载图片

由于加载图片导致OOM是很常见的情况。导致OOM的原因之一就是所加载的图片太大。如果我们不对原图做任何设置,就极其容易导致OOM。通过BitmapFactory.Options的核心思想就是加载我们所需尺寸的图片即可。很多时候,我们所需要的图片尺寸没有图片的原始尺寸那么大。
通过BitmapFactory.Options来缩放图片,主要用到了它的inSampleSize参数,即采样率。当inSampleSize为1时,采样后的图片与原图的大小相同。当inSampleSize为2时,采样后的图片的宽和高均为原图的1/2,像素数为原来的1/4.
加载图片的步骤:

  1. 将BitmapFactory.Options的inJustDecodeBounds参数设为true并加载图片。
  2. 从BitmapFactory.Options取出原始图片的宽高信息,对应为outWidth和outHeight参数。
  3. 根据所需要的图片大小计算采样率inSampleSize。
  4. 将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;
}