最近使用到了相机和图片的裁剪,在这里记录一下:
1,工具类
public class FileUtil { /** 格式化模板 */ public static final String TIME_FORMAT = "_yyyyMMdd_HHmmss"; //系统相机目录 public static final String CAMERA_PHOTO_DIR = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getParent(); private static String getTimeFormatName(String timeFormatHeader) { Date date = new Date(System.currentTimeMillis()); //必须加上 单引号 @SuppressLint("SimpleDateFormat") SimpleDateFormat dateFormat = new SimpleDateFormat("'" + timeFormatHeader + "'" + TIME_FORMAT); return dateFormat.format(date); } /** * @param timeFormatHeader 格式化的头(除去时间部分) * @param extension 后缀名 * @return 返回时间格式化后的文件名 */ public static String getFileNameByTime(String timeFormatHeader, String extension) { return getTimeFormatName(timeFormatHeader) + "." + extension; } /** * 这个方法是吧Uri 转换成真实路径,也就是photo的path */ public static String getRealFilePath(final Context context, final Uri uri) { if (uri == null) { return null; } final String scheme = uri.getScheme(); String date = null; if (scheme == null) { date = uri.getPath(); } else if (ContentResolver.SCHEME_FILE.equals(scheme)) { date = uri.getPath(); } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) { //从内容提供器中 查询数据 final Cursor cursor = context.getContentResolver().query(uri, new String[]{ MediaStore.Images.ImageColumns.DATA} , null, null, null); if (cursor != null) { if (cursor.moveToNext()) { final int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); if (index > -1) { date = cursor.getString(index); } } cursor.close(); } } return date; } }
2,设置 code
public class RequestCode { /** * 拍照 */ public static final int TAKE_PHOTO = 4; /** * 选照 */ public static final int PICK_PHOTO = 5; /** * 剪裁 */ public static final int CROP_PHOTO = UCrop.REQUEST_CROP; /** * 剪裁错误 */ public static final int CROP_ERROR= UCrop.RESULT_ERROR; /** * 扫描二维码 */ public static final int SCAN = 7; }
3,设置保存路径的bean类
public final class CameraImageBean { private Uri mPath = null; private CameraImageBean(){} private static final CameraImageBean INSTANCE = new CameraImageBean(); public static CameraImageBean getInstance(){ return INSTANCE; } public Uri getPath() { return mPath; } public void setPath(Uri mPath) { this.mPath = mPath; } }
4,动态请求权限,
如果是android 6.0 以上则需要申请权限。
申请权限我就不多说了,不懂的可以看下这篇文章 权限申请的简单封装
5,打开相机
private void takePhoto(){ //获取一个 名字, final String currentPhotoName = getPhotoName(); //拍照意图 final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //创建一个文件,路径为系统相册,第二个参数为名字 final File tempFile = new File(FileUtil.CAMERA_PHOTO_DIR,currentPhotoName); //如果手机 版本大于 AP24,兼容7.0以上的写法 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){ final ContentValues contentValues = new ContentValues(1); contentValues.put(MediaStore.Images.Media.DATA,tempFile.getPath()); //向内容提供器中插入一条数据,使用url 参数来确定要添加的表, //待添加的数保存在values 参数中,添加完成后 染回一个表示这条记录的url final Uri uri = DELEGATE.getContext().getContentResolver() .insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,contentValues); //需要将Uri 路径转化为 实际路径 final File readFile = FileUtils.getFileByPath(FileUtil.getRealFilePath(DELEGATE.getContext(),uri)); final Uri realUri = Uri.fromFile(readFile); //保存照片的路径 CameraImageBean.getInstance().setPath(realUri); //将拍的照片保存在指定的 URI intent.putExtra(MediaStore.EXTRA_OUTPUT,uri); }else { final Uri fileUri = Uri.fromFile(tempFile); CameraImageBean.getInstance().setPath(fileUri); intent.putExtra(MediaStore.EXTRA_OUTPUT,fileUri); } DELEGATE.startActivityForResult(intent,RequestCode.TAKE_PHOTO); } private String getPhotoName(){ return FileUtil.getFileNameByTime("IMG","jpg"); }
上面 FileUtils 是 utilcode 库里面的类,封装了非常多的工具,非常好用
implementation 'com.blankj:utilcode:1.23.7'
6,打开相册
/** * 打开 选择图片 */ private void pickPhoto(){ final Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("image/*"); intent.addCategory(Intent.CATEGORY_OPENABLE); DELEGATE.startActivityForResult(intent,RequestCode.PICK_PHOTO); }
7,回调
public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { switch (requestCode) { case RequestCode.TAKE_PHOTO: final Uri resultUri = CameraImageBean.getInstance().getPath(); //剪裁图片,第一个为原始路径,第二个为要保存的路径, UCrop.of(resultUri,resultUri) .withMaxResultSize(400,400) .start(getContext(),this); break; case RequestCode.PICK_PHOTO: if (data != null){ //从相册取的 原路径 final Uri pickPath = data.getData(); //从相册选择后需要有个路径存放剪裁后的图片 final String pickCropPath = LatteCamera.createCropFile().getPath(); //裁剪图片 UCrop.of(pickPath,Uri.parse(pickCropPath)) .withMaxResultSize(400,400) .start(getContext(),this); } break; case RequestCode.CROP_PHOTO: //裁剪完成后的uri final Uri cropUri = UCrop .getOutput(data); break; case RequestCode.CROP_ERROR: Toast.makeText(getContext(), "剪裁出错", Toast.LENGTH_SHORT).show(); break; default: break; } } }
上面裁剪 工具 使用的是 ucrop 库,
依赖如下:
implementation 'com.github.yalantis:ucrop:2.2.3-native'
具体配置和使用,可以在百度上搜一下。资料非常多