前言——项目中需要用到对用户头像的裁剪和上传功能。关于裁剪,一开始是想自己来做,但是觉得这个东西应该谷歌有开发吧,于是一搜索官方文档,果然有。于是,就果断无耻地用了Android自带有关于照片的*裁剪。因为时间太紧,虽然不太华丽,但是胜在能用,节省时间嘛。
具体是通过 Intent的action来实现的。
关键代码如下:
public void imageCut(Uri uri) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/*"); //开启裁剪功能 intent.putExtra("crop", "true"); //设定宽高的比例 intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); //设定裁剪图片宽高 intent.putExtra("outputX", 100); intent.putExtra("outputY", 100); //要求返回数据 intent.putExtra("return-data", true); startActivityForResult(intent, 100); }
返回数据后直接在onActivityResult里对返回的图片数据进行显示就行了,这里由于剪切后的图片较小,个人觉得应该不用考虑OOM的问题,问题是,在调用自带的裁剪功能的时候,由于没看源码,所以不知道在调整裁剪框的时候,显示的那副图片有没有进行压缩,如果没有进行压缩,那么当图片很大的时候,加载起来就很容易出现OOM了,明显对此由于是调用官方的API,我没有方法去解决它。唯一的办法就是不用它,而是自己去写一个,就可以避免这个问题。利用如下的代码进行压缩,很好地避免OOM问题。
/* * 压缩图片,返回的是压缩后的照片 */ public static Bitmap revitionImage(String path,int size){ Bitmap bitmap = null; try { //先用图片路径打开图片文件,缓冲到一个缓存输入流中 BufferedInputStream in = new BufferedInputStream(new FileInputStream( new File(path))); //用参数代表变量来记录当前照片的信息,比如图片大小 BitmapFactory.Options options = new BitmapFactory.Options(); //把inJustDecodeBounds设置为true,则完全不用分配内存就可以得到给位图文件bitmap的信息, //如此得到大小后,就可以对其进行7压缩,然后在内存中生成一个更小的bitmap,节省了内存 options.inJustDecodeBounds = true; //译码位图文件,只为了得到原图的信息 BitmapFactory.decodeStream(in ,null,options); //记得关闭流 in.close(); int i = 0; while(true){ //右移i位是因为下面的pow取一半了,新生成的图片是原来的二分之一 if (((options.outWidth >> i)<=size) && ((options.outHeight >> i) <=size)) { //这时候应取得照片了 in = new BufferedInputStream(new FileInputStream(new File(path))); //pow是次方方法,2的i次方,inSampleSize图片均分取样值,例如 //inSampleSize == 4 returns an image that is 1/4 the width/height of the original, and 1/16 the number of pixels. options.inSampleSize = (int)Math.pow(2.0, i); //这时候的图片已经符合我们设定的256大小了,所以要在设置false,允许输出,创建图片 //真正地生成一个有像素的,经过缩放的bitmap options.inJustDecodeBounds = false; bitmap = BitmapFactory.decodeStream(in,null,options);//获得n分之一原图,小于256*256 break; }else { i++; } } } catch (IOException e) { Log.i(TAG, "压缩图片出错"+e.toString()); } return bitmap; }
最后只能先用着了,有时间再深究或者自己折腾一个。下面是效果图,看着还行。
下面是一个关于本主题的DEMO。有需要的童鞋可以去看看。