首先说明下什么叫二次采样,为什么需要二次采样?二次采样就是对图片进行两次采集,有时候当我们从网上或者内存卡中加载一张图片很大时,比如一张一百多兆的地图图片,会出现内存溢出的异常,这时候就需要对图片进行处理,因为对于用户来说,只要能看清图片,可能并不需要这么大的图片,因此我们可以给出图片的缩略图。这里可能有个疑问,为啥不直接用设置固定的宽度和高度来解决呢?其实在设置之前也是需要先采集图片资源,而内存溢出异常并不是发生在显示图片的时候,而是图片太大,在采集时候出现异常。
那么要怎么做呢?我们既要采集到像素点,又不能在采集时把全部的像素点加载进来。首先,我们应该有个采集的思路,我们需要的是什么,需要缩略图,而缩略图需要个缩放比例,我们只要得到那个缩放比例,再按那个比例采集像素点,就可以得到想要的缩略图。那么,应该怎么得到缩放的比例,下面贴出一个处理图片的工具类:
public class BitmapUtils { public static Bitmap getBitmap(String path, int width, int height) { //在这里我们传进来三个参数,这是我们调用时想设置多大的缩略图还有原图的路径,这里我们只做本地的。 //然后我们实例化一个参数选项。 BitmapFactory.Options options=new BitmapFactory.Options(); //设置采集像素点时只采集边框,因为我们只要得到边框,再和传进来的宽度、高度一起处理就可以得到缩放比例。 options.inJustDecodeBounds=true; //按参数选项和图片路径采集图片的边框。 BitmapFactory.decodeFile(path, options); //得到原图的高度 int outHeight = options.outHeight; //得到原图的宽度 int outWidth = options.outWidth; //这里我们先设置缩放比例默认值为1. int scale=1; //这里当原图的宽度和高度除以比例大于传进来我们需要的宽、高时,让缩放比例每次扩大两倍,一般都是扩大2的n次倍。直到有一个所得到的值小于,为啥不是两个 都小于的时候退出循环呢,因为只要有一个大,就必须再进行缩放,直到两个都能放进我们需要的宽度和高度的控件中。 while (outHeight / scale>width || outWidth / scale>height) { scale*=2;//每次扩大两倍 } 第二次采集,这次按比例采集像素接着只需要传入参数调用工具类的这个方法就可以得到缩略图了。设置不仅提取边框还提取像素点
options.inJustDecodeBounds=false;
//将
得到的缩放比例设置给位图工厂的参数选项,
options.inSampleSize=scale;//设置图像的色彩模式options.inPreferredConfig=Bitmap.Config.ARGB_8888;
//然后返回一个按参数选项和路径采集的一个Bitmap
return BitmapFactory.decodeFile(path, options); }}