ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
1.从相册选择图片 2.对选择好的图片进行裁剪 3.裁剪之后的图片显示在界面上 #### 第三方引入 本篇使用了第三方库ucrop,github地址:[https://github.com/Yalantis/uCrop](https://github.com/Yalantis/uCrop) step.1 仓库位置 ~~~ allprojects { repositories { jcenter() maven { url "https://jitpack.io" } } } ~~~ step.2 导入包 ~~~ #轻量级使用这个 compile 'com.github.yalantis:ucrop:2.2.2' #更多功能的使用这个,要打1.5M左右 #compile 'com.github.yalantis:ucrop:2.2.2-native' ~~~ step.3 添加Activity ~~~ <activity android:name="com.yalantis.ucrop.UCropActivity" android:screenOrientation="portrait" android:theme="@style/Theme.AppCompat.Light.NoActionBar"/> ~~~ #### 布局和定义 随意定义一个ImageView。用到了一个缓存路径的辅助类,在本篇最后,和上一篇的是同一个。 ~~~ private ImageView picture; picture=(ImageView)findViewById(R.id.picture); ~~~ #### 进入相册 和之前单纯启动相机相比,增加了一个MediaStore.EXTRA_OUTPUT。 ~~~ Intent intent = new Intent(Intent.ACTION_PICK); intent.setDataAndType(MediaStore.Images.Media.INTERNAL_CONTENT_URI, "image/*");//相片类型 startActivityForResult(intent, 1); ~~~ #### 裁剪方法 定义一个公共的裁剪方法,其中用到了缓存文件这一块。这个是个辅助类,会写在本篇的最后。 ~~~ private void startUCrop(Uri imageUri){ //裁剪后保存到文件中 Uri destinationUri = Uri.fromFile(new File(CacheUtil.getCacheDirectory(this, null), "myCroppedImage.jpg")); UCrop uCrop = UCrop.of(imageUri, destinationUri); UCrop.Options options = new UCrop.Options(); //设置裁剪图片可操作的手势 options.setAllowedGestures(UCropActivity.SCALE, UCropActivity.ROTATE, UCropActivity.ALL); //设置toolbar颜色 options.setToolbarColor(ActivityCompat.getColor(this, R.color.colorPrimary)); //设置状态栏颜色 options.setStatusBarColor(ActivityCompat.getColor(this, R.color.colorPrimary)); //是否能调整裁剪框 // options.setFreeStyleCropEnabled(true); uCrop.withOptions(options); uCrop.withAspectRatio(1, 1); //比例 uCrop.start(this); } ~~~ #### 回调 两个回调,一个是选择图片之后的,直接调用裁剪;一个是裁剪之后的,把裁剪的显示在界面上。 ~~~ @Override protected void onActivityResult(int requestCode,int resultCode,Intent data){ if(resultCode==RESULT_OK) { switch (requestCode) { case 1: Uri selectedImage = data.getData(); startUCrop(selectedImage); break; case UCrop.REQUEST_CROP: final Uri croppedUri = UCrop.getOutput(data); try { if(croppedUri!=null) { Bitmap bit = BitmapFactory.decodeStream(getContentResolver().openInputStream(croppedUri)); picture.setImageBitmap(bit); } } catch (Exception e) { e.printStackTrace(); } break; } } } ~~~ #### 辅助类 ~~~ import android.content.Context; import android.os.Environment; import android.text.TextUtils; import android.util.Log; import java.io.File; public class CacheUtil { /** * 获取应用专属缓存目录 * android 4.4及以上系统不需要申请SD卡读写权限 * 因此也不用考虑6.0系统动态申请SD卡读写权限问题,切随应用被卸载后自动清空 不会污染用户存储空间 * @param context 上下文 * @param type 文件夹类型 可以为空,为空则返回API得到的一级目录 * @return 缓存文件夹 如果没有SD卡或SD卡有问题则返回内存缓存目录,否则优先返回SD卡缓存目录 */ public static File getCacheDirectory(Context context, String type) { File appCacheDir = getExternalCacheDirectory(context,type); if (appCacheDir == null){ appCacheDir = getInternalCacheDirectory(context,type); } if (appCacheDir == null){ Log.e("getCacheDirectory","getCacheDirectory fail ,the reason is mobile phone unknown exception !"); }else { if (!appCacheDir.exists()&&!appCacheDir.mkdirs()){ Log.e("getCacheDirectory","getCacheDirectory fail ,the reason is make directory fail !"); } } return appCacheDir; } /** * 获取SD卡缓存目录 * @param context 上下文 * @param type 文件夹类型 如果为空则返回 /storage/emulated/0/Android/data/app_package_name/cache * 否则返回对应类型的文件夹如Environment.DIRECTORY_PICTURES 对应的文件夹为 .../data/app_package_name/files/Pictures * {@link android.os.Environment#DIRECTORY_MUSIC}, * {@link android.os.Environment#DIRECTORY_PODCASTS}, * {@link android.os.Environment#DIRECTORY_RINGTONES}, * {@link android.os.Environment#DIRECTORY_ALARMS}, * {@link android.os.Environment#DIRECTORY_NOTIFICATIONS}, * {@link android.os.Environment#DIRECTORY_PICTURES}, or * {@link android.os.Environment#DIRECTORY_MOVIES}.or 自定义文件夹名称 * @return 缓存目录文件夹 或 null(无SD卡或SD卡挂载失败) */ public static File getExternalCacheDirectory(Context context,String type) { File appCacheDir = null; if( Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { if (TextUtils.isEmpty(type)){ appCacheDir = context.getExternalCacheDir(); }else { appCacheDir = context.getExternalFilesDir(type); } if (appCacheDir == null){// 有些手机需要通过自定义目录 appCacheDir = new File(Environment.getExternalStorageDirectory(),"Android/data/"+context.getPackageName()+"/cache/"+type); } if (appCacheDir == null){ Log.e("getExternalDirectory","getExternalDirectory fail ,the reason is sdCard unknown exception !"); }else { if (!appCacheDir.exists()&&!appCacheDir.mkdirs()){ Log.e("getExternalDirectory","getExternalDirectory fail ,the reason is make directory fail !"); } } }else { Log.e("getExternalDirectory","getExternalDirectory fail ,the reason is sdCard nonexistence or sdCard mount fail !"); } return appCacheDir; } /** * 获取内存缓存目录 * @param type 子目录,可以为空,为空直接返回一级目录 * @return 缓存目录文件夹 或 null(创建目录文件失败) * 注:该方法获取的目录是能供当前应用自己使用,外部应用没有读写权限,如 系统相机应用 */ public static File getInternalCacheDirectory(Context context, String type) { File appCacheDir = null; if (TextUtils.isEmpty(type)){ appCacheDir = context.getCacheDir();// /data/data/app_package_name/cache }else { appCacheDir = new File(context.getFilesDir(),type);// /data/data/app_package_name/files/type } if (!appCacheDir.exists()&&!appCacheDir.mkdirs()){ Log.e("getInternalDirectory","getInternalDirectory fail ,the reason is make directory fail !"); } return appCacheDir; } } ~~~