最近需要在安卓手机上做一个图片剪裁,就是选择一张照片,然后裁切,然后上传为头像。
那么一开始看的是极客学院的教程,那位老师虽然帮我入了个门,让我知道了大体怎么写,但不得不说他写的那个问题太多。他竟然先复制了一遍图片到自定义的内存路径上,然后再裁切。。我的天啊,反正我的红米这么搞卡死了,这可是平白无故把一个几兆的照片拷了一遍啊。。正确的做法是:先读取图片文件,然后裁,然后存裁完的到指定文件。
那个教程里使用的是com.android.camera.action.CROP,这个action是调用系统自带的图片裁切功能(什么叫通过action调用activity我并不是很清楚,日后再说),所以存在很多问题,主要是两点:
1、不同厂家手机做出来的裁切功能不一样,界面都不一样,并且你不能或者很难自定义裁切界面的UI,甚至在测试时发现有的手机上会在裁切时候自动把图片转了九十度,我们当然不想出现这么差的体验。
2、启动这个自带crop,你需要传进去一个待裁剪图片的uri,uri有很多不同的scheme类型,比如file、content,对于安卓4.4之前的版本,这个crop还好用,但4.4之后,uri出现了形如 content://com.android.providers.media.documents/document/image%2706 这样的类型,这个crop就会报错崩溃,我也实在不知道这是手机厂家的错还是谷歌的错。
那么我去stackoverflow上查了一下解决办法:http://stackoverflow.com/questions/26295868/croping-camera-intent-in-android-4-4
大神说有一些用于裁切图片的开源类库十分好用,比如下面这几个:
https://github.com/lvillani/android-cropimage
https://github.com/biokys/cropimage
https://github.com/MMP-forTour/cropimage
https://github.com/dtitov/pickncrop
我一看这个好啊,显然不用自己写嘛,真心感谢贡献开源的前辈!助力中小企业成长!!
那么我用了第一个,这个可以放心使用,readme里有说这个开源项目遵守阿帕奇开源协议,在它的协议书里写明了可以用于商业用途。运行其sample,真的非常好用,不存在系统自带crop的种种问题,那么我按方法导入了这个类库作为一个module,但之后发现似乎不能修改其布局文件和代码,我也不太清楚怎么回事,大概是我导入的姿势不对(这个问题真心跪求高人指导),于是为了方便起见,我就干脆把代码复制粘贴到项目里了,也正好可以方便的修改其布局、代码之类的。
那么,首先确定你正确的把所有要用到的代码粘贴到项目里之后,按如下方法调用即可:
启动从相册选择:
startActivityForResult(MediaStoreUtils.getPickImageIntent(UserIconActivity.this), GALLERY_REQUEST_CODE);
onActivityResult中设置裁剪完的图片保存在哪个文件中(MethodUtils是我自己用的工具类,返回图片文件):
//创建剪裁完的图像文件
File croppedImageFile = MethodUtils.getUserIconFile();
Uri croppedImageUri = Uri.fromFile(croppedImageFile);
onActivityResult中对相册选择的返回处理:
//图库请求的返回处理
if (requestCode == GALLERY_REQUEST_CODE && resultCode == RESULT_OK) {
//当用户从图库挑选完一张图片,启动 CropImage Activity
startImageZoom(data.getData(), croppedImageUri);
}
/** 启动图片剪裁
*
* @param uri 待裁剪图片文件的uri
* @param croppedImageUri 剪裁完图片文件的uri
*/
private void startImageZoom(Uri uri, Uri croppedImageUri) {
//设置输出图片文件的Uri,裁剪框设为蓝色,并将裁切出的大小设置为200*200 像素大小的正方形
CropImageIntentBuilder cropImage = new CropImageIntentBuilder(200, 200, croppedImageUri);
cropImage.setOutlineColor(0xFF03A9F4);
cropImage.setSourceImage(uri);
startActivityForResult(cropImage.getIntent(this), CROP_REQUEST_CODE);
}
//裁剪请求的返回处理
if (requestCode == CROP_REQUEST_CODE && resultCode == RESULT_OK) {
Bitmap bm = BitmapFactory.decodeFile(croppedImageFile.getAbsolutePath());
iv_UserIcon.setImageBitmap(bm);
}
//放这么一张图片上去的意思是,能自己定义裁切界面比看美女照片还爽。