一个适用于 Android 的图像裁剪库。
GitHub 地址:uCrop
目前,您可以更改:
- 图像压缩格式(例如PNG、JPEG、WEBP)、压缩
- 图像压缩质量 [0 - 100]。无损的 PNG 将忽略质量设置。
- 是否同时启用所有手势
- 从源 Uri 解码并在裁剪视图中使用的位图的最大大小。如果要覆盖默认行为。
- 切换是否显示裁剪框/指南
- 设置裁剪框/行/列的颜色/宽度/计数
- 选择你想要矩形还是椭圆(options.setCircleDimmedLayer(true))裁剪区域
- UI 颜色(工具栏、状态栏、活动小部件状态)
本篇将实现在 Android 7.0 中拍照以及相册裁剪。
二、实战1. 效果图
2. 添加依赖
allprojects {
repositories {
jcenter()
maven { url "https://jitpack.io" }
}
}
--------------------------分割线----------------------------------
//Butter Knife
implementation "com.jakewharton:butterknife:${butterknife_version}"
annotationProcessor "com.jakewharton:butterknife-compiler:${butterknife_version}"
// glide
implementation "com.github.bumptech.glide:glide:${glide_version}"
annotationProcessor "com.github.bumptech.glide:compiler:${glide_version}"
// uCrop
implementation "com.github.yalantis:ucrop:${ucrop_version}"
// 运行时权限
implementation "pub.devrel:easypermissions:${easy_version}"
// 工具类
implementation "com.blankj:utilcodex:${utilcodex_version}"
3. 在清单文件中,添加权限、配置 FileProvider
...
4. 在 res 目录下新建文件夹 xml 然后创建资源文件 file_paths_public
5. 调用相机拍照
/**
* 拍照
*/
private void camera() {
File file = new File(Config.SAVE_REAL_PATH, System.currentTimeMillis() + ".jpg");
LogUtils.e(file.getPath());
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//Android7.0以上URI
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//通过FileProvider创建一个content类型的Uri
mProviderUri = FileProvider.getUriForFile(this, "com.kevin.ucropdemo.fileprovider", file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mProviderUri);
//添加这一句表示对目标应用临时授权该Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
mUri = Uri.fromFile(file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mUri);
}
try {
startActivityForResult(intent, RESULT_CODE_1);
} catch (ActivityNotFoundException anf) {
ToastUtils.showShort("摄像头未准备好!");
}
}
6. 相册选图
/**
* 相册选图
*/
private void selectImg() {
Intent pickIntent = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
pickIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(pickIntent, RESULT_CODE_2);
}
7. 裁剪图片
/**
* 使用UCrop进行图片剪裁
*
* @param uri
*/
public void cropRawPhoto(Uri uri) {
UCrop.Options options = new UCrop.Options();
// 修改标题栏颜色
options.setToolbarColor(getResources().getColor(R.color.teal_200));
// 修改状态栏颜色
options.setStatusBarColor(getResources().getColor(R.color.teal_700));
// 隐藏底部工具
options.setHideBottomControls(true);
// 图片格式
options.setCompressionFormat(Bitmap.CompressFormat.JPEG);
// 设置图片压缩质量
options.setCompressionQuality(100);
// 是否让用户调整范围(默认false),如果开启,可能会造成剪切的图片的长宽比不是设定的
// 如果不开启,用户不能拖动选框,只能缩放图片
options.setFreeStyleCropEnabled(true);
// 设置图片压缩质量
options.setCompressionQuality(100);
// 圆
options.setCircleDimmedLayer(true);
// 不显示网格线
options.setShowCropGrid(false);
FileUtils.createOrExistsDir(Config.SAVE_REAL_PATH);
// 设置源uri及目标uri
UCrop.of(uri, Uri.fromFile(new File(Config.SAVE_REAL_PATH, System.currentTimeMillis() + ".jpg")))
// 长宽比
.withAspectRatio(1, 1)
// 图片大小
.withMaxResultSize(200, 200)
// 配置参数
.withOptions(options)
.start(this);
}
8. 剪切完图片的回掉
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == UCrop.RESULT_ERROR) {
mCameraTv.setText(UCrop.getError(data) + "");
return;
}
if (resultCode == RESULT_OK) {
switch (requestCode) {
case RESULT_CODE_1:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
cropRawPhoto(mProviderUri);
} else {
cropRawPhoto(mUri);
}
break;
case RESULT_CODE_2:
LogUtils.i("onActivityResult: " + data.getData());
cropRawPhoto(data.getData());
break;
case UCrop.REQUEST_CROP:
LogUtils.i("onActivityResult: " + UCrop.getOutput(data));
mCameraTv.setText(UCrop.getOutput(data) + "");
Glide.with(this)
.load(UCrop.getOutput(data))
.into(mCameraImg);
break;
default:
break;
}
}
}