从相册选相片,或者拍照选相片再裁剪是众多app都有的功能。做法很简单,这里我写了一个demo实现头像选择。
啥也不说了,先上效果图:
实现步骤:
1.弹框选择框所用的popupwindow
private void showPopupwindow(){
DoubleSelectPopupWindow popupWindow = new DoubleSelectPopupWindow(this);
popupWindow.showAtLocation(rootView, Gravity.BOTTOM,0,0);
popupWindow.init("头像选择",strs);
popupWindow.setOnSelectListener(new DoubleSelectPopupWindow.ICallIntListener() {
@Override
public void callBack(int pos) {
if(pos == 0){
choosePicUtil.takePic(ChoosePicUtil.CODE_CAMERA_REQUEST);
}else{
choosePicUtil.choosePic();
}
}
});
}
2.takepic()和choosePic()方法;分别使用MediaStore.ACTION_IMAGE_CAPTURE、MediaStore.ACTION_GET_CONTENT两个意图调起系统拍照和图片选择。
getRealFilePath(final Uri uri )可将裁剪图片的uri转为sd卡路径。
/**
* 选择图片或拍照工具
*/
public class ChoosePicUtil {
private Context context;
private Uri imageUri;
private Uri imageCropUri;
public static final int CODE_CAMERA_REQUEST = 0;
public static final int CODE_CHOOSE_REQUEST = 1;
public static final int CODE_CAMERA_CROP_REQUEST = 2;
public ChoosePicUtil(Context context, Uri imageUri, Uri imageCropUri){
this.context = context;
this.imageUri = imageUri;
this.imageCropUri = imageCropUri;
}
/**
* 拍照
* @param resultCode
*/
public void takePic(int resultCode){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra("return-data", false);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true);
((Activity)context).startActivityForResult(intent, resultCode);
}
/**
* 裁剪图片
* @param uri
*/
public void cropImg(Uri uri) {
Intent intent = new Intent("com.android.camera.action.CROP"); //调用裁剪
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1); //设置宽高比例为1:1
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 700); //设置裁剪图片宽高700x700
intent.putExtra("outputY", 700);
intent.putExtra("return-data", false);
intent.putExtra("scale",true);
intent.putExtra("scaleUpIfNeeded", true); //防止出现黑边框
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageCropUri);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); //设置输出格式
intent.putExtra("noFaceDetection", true);
((Activity)context).startActivityForResult(intent, CODE_CAMERA_CROP_REQUEST);
}
public void choosePic(){
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
((Activity)context).startActivityForResult(intent, CODE_CHOOSE_REQUEST);
}
public String getRealFilePath(final Uri uri ) {
if ( null == uri ) return null;
final String scheme = uri.getScheme();
String data = null;
if ( scheme == null )
data = uri.getPath();
else if ( ContentResolver.SCHEME_FILE.equals( scheme ) ) {
data = uri.getPath();
} else if ( ContentResolver.SCHEME_CONTENT.equals( scheme ) ) {
Cursor cursor = context.getContentResolver().query( uri, new String[] { MediaStore.Images.ImageColumns.DATA }, null, null, null );
if ( null != cursor ) {
if ( cursor.moveToFirst() ) {
int index = cursor.getColumnIndex( MediaStore.Images.ImageColumns.DATA );
if ( index > -1 ) {
data = cursor.getString( index );
}
}
cursor.close();
}
}
return data;
}
}
3.设置选择图片和裁剪图片的路径,设置给第二步的ChoosePicUtil类。
File file = new File(picSavePath + "/avator.jpg");
imageUri = Uri.fromFile(file);
File cropFile = new File(picSavePath + "/avator_crop.jpg");
imageCropUri = Uri.fromFile(cropFile);
choosePicUtil = new ChoosePicUtil(this,imageUri,imageCropUri);
4.在onActivityResult方法中获取startActivityforResult()裁剪图片路径的回调。回调接收的流程是:拍照或选择图片分别走case1,case3;都会调用cropImg()去裁剪图片,裁剪完回调再走case2情况,从data中获取裁剪后的uri。
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK){
switch (requestCode){
case ChoosePicUtil.CODE_CAMERA_REQUEST:
choosePicUtil.cropImg(imageUri);
break;
case ChoosePicUtil.CODE_CAMERA_CROP_REQUEST:
Bundle extras = data.getExtras();
if (extras != null) {
//获取bitmap
Bitmap bitmap = BitmapFactory.decodeFile(choosePicUtil.getRealFilePath(imageCropUri));
ivAvator.setImageBitmap(bitmap);
}
break;
case ChoosePicUtil.CODE_CHOOSE_REQUEST:
choosePicUtil.cropImg(data.getData());
break;
}
}
}
不过注意:Android7.0以上系统尝试传递 file:// URI 会触发 FileUriExposedException,就需要使用FileProvider来获取。