Android手机裁剪从相册选取或拍照的照片

本文参考了《第一行代码》里的部分代码,不过由于较新版本的Android更改了有关相册的API,导致了基于其代码开发的应用在新的Android系统里无法正常运行。经过一番折腾,本人找到如下方法,解决了因兼容性带来的问题。

建立图片文件存放bitmap

在拍照或从相册选取照片前,需要临时在本地新建一个文件存在图片。

1
2
3
4
5
6
7
8
9
File outputImage = new File(Environment.getExternalStorageDirectory(),"pic.jpg");
try{
if(outputImage.exists()){
outputImage.delete();
}
outputImage.createNewFile(); //保存照片
}catch (IOException e){
e.printStackTrace();
}

记得把文件outputImage转换为Uri对象,便于之后的操作。

1
Uri imageUri = Uri.fromFile(outputImage); //转换为Uri对象

拍照后裁剪

启动相机

1
2
3
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
startActivityForResult(intent,TAKE_PHOTO);

在onActivityResult()方法里处理返回后的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case TAKE_PHOTO:
if (resultCode == RESULT_OK) { //若拍摄好后确定了图像,则进入修剪图像操作
Intent intent = new Intent("com.android.camera.action.CROP"); //修剪图像操作
intent.setDataAndType(imageUri, "image/*");
intent.putExtra("scale", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, SHOW_PHOTO); // 启动裁剪程序
}
break;
...

从相册选取照片

打开相册

1
2
3
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, CAMERA_CHOOSE);

从相册返回,对照片进行进一步处理。Bitmap的compress方法可通过默认的压缩算法把图像保存到本地,通过第二个参数设置压缩比,如果其值为100,表示不压缩,如果为10,表明压缩90%。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
case CAMERA_CHOOSE:
if (resultCode == RESULT_OK) {
Bitmap bitmap = null;
Uri uri = data.getData();
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(outputImage)); //保存图像到指定路径
Intent intent = new Intent("com.android.camera.action.CROP"); //修剪图像操作
intent.setDataAndType(imageUri, "image/*");
intent.putExtra("scale", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, SHOW_PHOTO); // 启动裁剪程序
} catch (IOException e) {
e.printStackTrace();
}
}
break;
...

显示裁剪后的照片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
...
case SHOW_PHOTO:
if (resultCode == RESULT_OK) { //若图像修剪完成后,打开另一个Activity并显示出来
try {
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
ivData.setImageBitmap(bitmap); //显示裁剪后的照片
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
break;
...