北仑网站推广,网页设计有哪些,广东网络建设有限公司,北京注册公司需要什么手续和证件书接上文 Android 设置头像 - 相册拍照#xff0c;通过相册和照片的设置就可以获取到需要的头像信息#xff0c;但是在通常情况下#xff0c;我们还想要实现针对头像的裁剪功能和圆形头像功能。 先上截图#xff1a;
图像裁剪 通常裁剪可以分为程序自动裁剪和用户选择裁剪… 书接上文 Android 设置头像 - 相册拍照通过相册和照片的设置就可以获取到需要的头像信息但是在通常情况下我们还想要实现针对头像的裁剪功能和圆形头像功能。 先上截图
图像裁剪 通常裁剪可以分为程序自动裁剪和用户选择裁剪两种方式程序自动裁剪及程序中设置固定的裁剪比例然后系统自动进行裁剪Glide即可实现该功能。但这种实现方式往往不能满足用户实际需求及实际裁剪需要用户进行选择图片裁剪范围。下面将提供两种图片裁剪的实现逻辑出了本文描述的裁剪实现逻辑外还有自定义裁剪view等其他实现逻辑由于技术有限再次仅仅阐述较为简单的两种实现逻辑。
第三方裁剪库 目前存在很对开源的第三方Android裁剪工具库通过比较uCrop的裁剪工具库较为流行本文将以该裁剪工具集成为例进行说明。uCrop的GitHub地址点这里。通过README文档可知集成该工具需要以下操作
gradle引入AndroidManifest.xml中声明Activity业务代码中调用UCrop进行裁剪通过onActivityResult接收裁剪结果intent 上述四个过程在github中作者都进行了详细说明下面进行我理解的简单说明 采用该工具需要传入目标Uri 使用该工具进行裁剪需要输入源Uri和目标Uri及被参见图片Uri和裁剪后图片存放的Uri不同Android版本的Uri获取方式不同Uri相关内容本人也一知半解后续了解后将另文说明。 AndroidManifest.xml中声明Activity 相信使用module开发或者引入过arr资源包的都清楚需要在AndroidManifest.xml中引入第三方arr的Activity文件。根据这个说明不难推断出Ucrop为一个arr资源包并非jar包并且结合网上了解到的自定义裁剪试图的实现逻辑不难推断出Ucrop也实现了一个自定义Activity进行裁剪当用户发起裁剪请求时将跳转到Ucrop的Activity中待裁剪完成后进行回跳并携带裁剪结果。
通过onActivityResult接收裁剪结果intent UCrop.start()方法将进行裁剪通过查看源码该方法调用了activity.startActivityForResult(getIntent(activity), requestCode);方法因此需要重写onActivityResult方法进行接收回跳携带参数。但是由于startActivityForResult即将弃用所以这种方式我不建议使用。考虑是否可以通过重写UCrop.start方法通过ActivityResultLauncher.launch的方法进行裁剪调用。
系统默认裁剪intent调用 系统默认裁剪实现是裁剪过程中最简单的实现方式按照百度结果只需要创建一个Intent intent new Intent(“com.android.camera.action.CROP”);意图并进行相关参数配置即可。下面首先展示我的实现逻辑
首先配置ActivityResultContract如下
/*** 裁剪照片的contract** author baiyang* since 2024-04-28*/
public class CropImageResultContract extends ActivityResultContractIntent, Intent {public static final String AUTHORITY com.ldr.imosApp.provider;public static final String IMAGE_TYPE image/jpeg;public static final String JPG_TYPE jpg;private String type;private Uri uri;NonNullOverridepublic Intent createIntent(NonNull Context context, Intent input) {input.putExtra(crop, true);input.putExtra(aspectX, 1);input.putExtra(aspectY, 1);input.putExtra(outputX, 256);input.putExtra(outputY, 256);input.putExtra(return-data, true);String mimeType null;String fileName null;mimeType IMAGE_TYPE;fileName System.currentTimeMillis() . JPG_TYPE;Uri mediaUri MediaStore.Images.Media.EXTERNAL_CONTENT_URI;if (Build.VERSION.SDK_INT Build.VERSION_CODES.Q) {ContentValues values new ContentValues();values.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName);values.put(MediaStore.MediaColumns.MIME_TYPE, mimeType);values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM);uri context.getContentResolver().insert(mediaUri, values);} else {uri FileProvider.getUriForFile(context, AUTHORITY,new File(context.getExternalCacheDir().getAbsolutePath(), fileName));}input.putExtra(MediaStore.EXTRA_OUTPUT, uri);return input;}/*** 返回拍照结果因为在调用相机的过程中设置了EXTRA_OUTPUT因此返回时intentnull需要重新设置一下** param resultCode* param intent* return*/Overridepublic Intent parseResult(int resultCode, Nullable Intent intent) {if (resultCode ! Activity.RESULT_OK) {return null;}intent new Intent();intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);return intent;}
}上述代码在拍照图库文档中已经进行详细说明在此需要补充一点疏漏是我们在createIntent方法中创建了一个Uri那么intent返回的时候通过getData就不能获取裁剪结果的Uri了而且我们创建的这个Uri会导致裁剪后的图片将作为一个资源存放到了我们的通过中这也是为什么在Android 设置头像 - 相册拍照一文从图库中选择照片的createIntent方法中我没有创建Uri的原因如果创建了会导致图库中存在两张重复的图片。在上述代码实现初期我并没有创建Uri直接通过getData进行获取Uri在模拟器上进行测试是可以通过的但是使用真机测试的过程中依旧会出现裁剪正常进行但是裁剪结果getDatanull的情况。目前原因不详怀疑可能是通过intent调用默认的裁剪实现后裁剪的返回结果在不同机型上进行了不同方式的返回因此通过创建Uri进行接收裁剪结果是最稳妥的实现方式
进行裁剪结果回调函数实现 /*** 裁剪照片的回调函数*/private final ActivityResultCallbackIntent cropCallback result - {if (Objects.nonNull(result)) {Uri uri result.getParcelableExtra(MediaStore.EXTRA_OUTPUT);Glide.with(PersonalInformationActivity.this).load(uri).into(binding.headSculpture);} else {LogUtils.e(裁剪照片回调失败未回传相关数据);}};即获取结果后直接通过Glide进行图片回显。后续的圆形图像可以通过Glide进行实现。
intent调用 在进行intent调用之前首先需要获取ActivityResultLauncher如下 cropResultLauncher registerForActivityResult(new CropImageResultContract(),cropCallback);intent调用是需要进行裁剪而裁剪过程应该是在选择图片或者拍照后进行因此需要修改原拍照图库的回调函数进行调用裁剪的intent代码如下 /*** 拍照或者选择图库照片后回调*/private final ActivityResultCallbackIntent callback result - {if (Objects.nonNull(result)) {Uri uri result.getParcelableExtra(MediaStore.EXTRA_OUTPUT);// 进行裁剪Intent intent new Intent(com.android.camera.action.CROP);intent.setDataAndType(uri, image/*);cropResultLauncher.launch(intent);
// Glide.with(getApplicationContext()).load(uri).into(binding.headSculpture);} else {LogUtils.e(拍照、录像数据回调失败未回传相关数据);}};上述及使用系统默认的裁剪工具进行裁剪的实现方式不同手机不同android版本的系统默认裁剪工具并不相同因此最终实现效果也不相同由于手头真机数量有限并不能针对更多机型进行测试所以并不确定上述逻辑实现可以适配所以手机而且对于没有系统默认裁剪工具的机型上述代码无法进行裁剪而Ucrop工具可以实现裁剪。
intent到底是什么 Intent意图主要是解决Android应用的各项组件之间的通讯。 Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述Android则根据此Intent的描述负责找到对应的组件将 Intent传递给被调用的组件并完成组件的调用。 因此Intent在这里起着一个媒体中介的作用专门提供组件互相调用的相关信息实现调用者与被调用者之间的解耦。 上面为百度词条对其的解释intent可以实现各个组件的通信。回忆我们实现的Activity跳转逻辑通过startActivity(intent);方法进行跳转intent我们一般进行下面定义
Intent intent new Intent();
intent.setClass(getApplicationContext(), MainActivity.class);上述代码表示从当前Activity跳转到MainActivity,可以看到我们并没有进行MainActivity初始化跳转等特殊设置我没有深入研究Android底层源码但是不难推测出当startActivity(intent);方法被调用后intent意图交由Android底层进行处理Android系统根据intent传参判断该意图需求如果是Activity跳转则从Activity注册表中获取目的Activity并进行生命周期的调用个人揣测不准欢迎斧正。 上面例子为Activity跳转一般都是同一APP内部跳转但是当我们进行拍照、调用通讯录等系统级别的操作时也是借助Intent进行实现的那么可以大胆推测intent的处理时交由Android底层进行处理他并不是某个app内部进行处理的当底层接收到一个访问相机的intent时将判断是否具备访问权限如果具备则调用相机。 通过上述分析我们可以继续推测调用系统裁剪及Intent intent new Intent(“com.android.camera.action.CROP”);这个意图在交由Android底层进行处理的时候Android底层将从它的Activity注册表中找到相关Activity进行跳转。在此引申下属代码 activityandroid:name.ui.GuideActivityandroid:exportedtrueintent-filteraction android:nameandroid.intent.action.MAIN /category android:nameandroid.intent.category.LAUNCHER //intent-filter/activity 这段代码写Android的都清楚Android首界面的设置设置Android受界面需要声明intent-filter标签并且需要设置android:exported“true”表明该Activity允许外部访问及允许Android底层进行调用启动。
圆形头像 圆形头像的实现可记住Glide工具按照如下代码 RequestOptions options new RequestOptions().circleCropTransform();Glide.with(PersonalInformationActivity.this).load(uri).apply(options).into(binding.headSculpture);在进行into到目标view的过程中Glide使用了bitmapTransform进行转化使用的是CropCircleTransformation实现该实现类将图片转化为圆形图片。通过借助Glide的实现圆形头像较为简单在此不再深入Gilde的具体细节。
总结 通过裁剪和圆形头像的实现更加深入的对ActivityResultLauncher进行了学习并在实现的过程中对Intent有了更加深入的思考如果本文内容存在问题欢迎各位大佬进行斧正。总结本文内容。
Ucrop工具实现图片裁剪Intent系统默认裁剪实现类intent深入思考Gilde圆形图片的实现