定义:
private BitmapFactory.Options opt=new BitmapFactory.Options(); private Bitmap bitmap = null; private ImageView mimageview ; mimageview = (ImageView)this.findViewById(R.id.pic_voice_image);
加载图片
private void LoadPicture() { options=new Options(); options.inDither=false; /*不进行图片抖动处理*/ options.inPreferredConfig=null; /*设置让解码器以最佳方式解码*/ options.inSampleSize=1; /*图片长宽方向缩小倍数*/ bitmap = BitmapFactory.decodeFile(path,options);//其中path是图片路径 mimageview.setImageBitmap(bitmap); }
在需要加载图片的地方执行:
mimageview.setImageBitmap(bitmap);
测试效果:图片在1M左右以及以下的时候切换是没问题的,但是一旦图片达到了3M的时候Bitmap内存就溢出了。虽然说Bitmap的内存是8M,但是实际上会有误差,切换图片时系统还来不及回收Bitmap上一次资源完毕又要往里面写流,导致oom错误。所以这种方法还不是很优的方法。
这种方式相对第一种方式来说会更节省内存,方法如下:
/** * 以最省内存的方式读取本地资源的图片 */ public static Bitmap readBitMap(String path,BitmapFactory.Options opt,InputStream is){ opt.inPreferredConfig = Bitmap.Config.RGB_565; opt.inPurgeable = true; opt.inInputShareable = true; opt.inSampleSize=2;//二分之一缩放,可写1即100%显示 //获取资源图片 try { is = new FileInputStream(path); } catch (FileNotFoundException e) { e.printStackTrace(); } return BitmapFactory.decodeStream(is,null,opt); }
在需要加载图片的地方执行:
mimageview.setImageBitmap(readBitMap(path,opt,is));
测试结果:3M的大图切换没问题,相对第一种来说优点是完全不用考虑切换大图时Bitmap内存不及回收内存导致内存溢出问题,只要做好InputStream流的开关操作就好了。
这种方式相对第二种方式来说会更优化,因为一旦图片超过了3M,甚至更大的时候方式二也是不管用的。以下的方法是按着设定的分辨率让如片按比例压缩,保证不管是多大的图片也能无压力显示出来。以下是完整代码:
/*********** * @获得原始流* ***********/ public InputStream toInputStream(String path) throws Exception{ FileInputStream is = new FileInputStream(path.replace("file://", "")); return is; } /************ * 返回压缩后的流* ************/ public Bitmap toBitmap(String path, int reqWidth, int reqHeight) throws Exception{ Bitmap bm = null; InputStream inputStream = toInputStream(path); // 远程读取输入流 if (inputStream == null){ return null; } BitmapFactory.Options options = new BitmapFactory.Options(); // 当inJustDecodeBounds设为true时,不会加载图片仅获取图片尺寸信息 options.inJustDecodeBounds = true; // 获取图片大小 BitmapFactory.decodeStream(inputStream, null, options); // 获取图片压缩比 int size = calculateInSampleSize(options, reqWidth, reqHeight); if ( size < 0 ){ return null; } Log.e("size", String.valueOf(size)); options.inSampleSize = size; // 找到合适的倍率 // 当inJustDecodeBounds设为false,加载图片到内存 options.inJustDecodeBounds = false; inputStream = toInputStream(path); // 远程读取输入流,要再读一次,否则之前的inputStream已无效了 bm = BitmapFactory.decodeStream(inputStream, null, options); return bm; } /********************************* * @function: 计算出合适的图片倍率 * @options: 图片bitmapFactory选项 * @reqWidth: 需要的图片宽 * @reqHeight: 需要的图片长 * @return: 成功返回倍率, 异常-1 ********************************/ private int calculateInSampleSize(Options options, int reqWidth, int reqHeight) { // 设置初始压缩率为1 int inSampleSize = 1; try{ // 获取原图片长宽 int width = options.outWidth; int height = options.outHeight; // reqWidth/width,reqHeight/height两者中最大值作为压缩比 int w_size = width/reqWidth; int h_size = height/reqHeight; inSampleSize = w_size>h_size?w_size:h_size; // 取w_size和h_size两者中最大值作为压缩比 Log.e("inSampleSize", String.valueOf(inSampleSize)); }catch(Exception e){ return -1; } return inSampleSize; }
在需要加载图片的地方执行:
mimageview.setImageBitmap(toBitmap(path, picwidth, picheigth));
测试该方法可以显示出来很大的图片,只要你设定的长宽合理。