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;
}
}
~~~