1.概述
在实际开发中,我们经常需要让用户上传一些图片资源,这些资源可以是从系统拍照后获得,有的是直接从相册等文件中获取。然而现在的手机自带相机的分辨率还是很高的,鉴于Android App 16M原则,一张图片的所占资源太多,我们需要对于进行适当裁剪后加以利用。今天就像大家简单介绍一下图片裁剪的一种有效方法。为了简单直观,先上几张图片然大家有个直观的认识。
2.使用系统相机获取图片资源
// 拍照--启动系统相机
public void toPhotograph(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, PHOTOGRAPH_REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (null == data || Activity.RESULT_CANCELED == resultCode) {
return;
}
获取返回的图片
if (PHOTOGRAPH_REQUEST_CODE == requestCode
&& Activity.RESULT_OK == resultCode) {
Bundle bundle = data.getExtras();
Bitmap bmp = (Bitmap) bundle.get("data");
userPhotoImg.setImageBitmap(bmp);
}
}
3.是系统中的相册获取图片资源
// 从相册选择--从系统相册中选择图片
public void toSelectPictureFromAlbum(View view) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_PICK);
intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, ABLUM_REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (null == data || Activity.RESULT_CANCELED == resultCode) {
return;
}
// 从相册中选择图片
if (ABLUM_REQUEST_CODE == requestCode) {
Uri uri = data.getData();
Bitmap bmp = decodeUriAsBitmap(uri);
userPhotoImg.setImageBitmap(bitmap);
}
}
private Bitmap decodeUriAsBitmap(Uri uri) {
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream(getContentResolver()
.openInputStream(uri));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
return bitmap;
}
4.图片裁剪
Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
intent.setType("image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 100);
intent.putExtra("outputY", 100);
intent.putExtra("scale", true);
intent.putExtra("return-data", false);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", false); // no face detection
startActivityForResult(intent, ABLUM_REQUEST_CODE);
对Intent中添加的参数进行说明
附加选项 数据类型 描述
crop String 发送裁剪信号
aspectX int X方向上的比例
aspectY int Y方向上的比例
outputX int 裁剪区的宽
outputY int 裁剪区的高
scale boolean 是否保留比例
return-data boolean 是否将数据保留在Bitmap中返回
data Parcelable 相应的Bitmap数据
circleCrop String 圆形裁剪区域?
MediaStore.EXTRA_OUTPUT ("output") URI 将URI指向相应的file:///...,详见代码示例
主要有两种方式从这个Intent中取得返回的bitmap:获取内部数据或者提供一个Uri以便程序可以将数据写入。
方法1:
如果你将return-data设置为“true”,你将会获得一个与内部数据关联的Action,并且bitmap以此方式返回:(Bitmap)extras.getParcelable("data")。注意:如果你最终要获取的图片非常大,那么此方法会给你带来麻烦,所以你要控制outputX和outputY保持在较小的尺寸。鉴于此原因,在我的代码中没有使用此方法((Bitmap)extras.getParcelable("data"))。
方法2:
如果你将return-data设置为“false”,那么在onActivityResult的Intent数据中你将不会接收到任何Bitmap,相反,你需要将MediaStore.EXTRA_OUTPUT关联到一个Uri,此Uri是用来存放Bitmap的。但是还有一些条件,首先你需要有一个短暂的与此Uri相关联的文件地址,当然这不是个大问题(除非是那些没有sdcard的设备)。
5.完整代码
package com.example.qq.activity.my.user;
import java.io.FileNotFoundException;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.ImageView;
import com.example.qq.R;
/**
* Description: 修改用户头像
*
* @author danDingCongRong
* @Version 1.0.0
* @Created at 2014-8-9 00:44:38
* @Modified by [作者] on [修改日期]
*/
public class UpdateUserPhotoActivity extends Activity {
private static final int CROP_USER_PHOTO_REQUEST_CODE = 0;
private static final int USER_PHOTO_REQUEST_CODE = 1;
private ImageView userPhotoImg;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_update_user_photo);
initView();
}
private void initView() {
userPhotoImg = (ImageView) findViewById(R.id.userPhotoImg);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (null == data) {
return;
}
switch (requestCode) {
case USER_PHOTO_REQUEST_CODE:
if (Activity.RESULT_OK == resultCode && data.hasExtra("UserPhoto")) {
String fileName = data.getStringExtra("UserPhoto");
Bitmap bitmap = BitmapFactory.decodeFile(fileName);
Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, 100, 100,
new Matrix(), true);
userPhotoImg.setImageBitmap(resizeBmp);
}
break;
case CROP_USER_PHOTO_REQUEST_CODE:
if (data.hasExtra("UserPhotoUri")) {
Uri uri = data.getParcelableExtra("UserPhotoUri");
Bitmap bitmap = decodeUriAsBitmap(uri);
userPhotoImg.setImageBitmap(bitmap);
}
break;
default:
break;
}
}
// 设置头像
public void setHeadPortrait(View view) {
Intent intent = new Intent();
intent.setClass(this, SetUserHeadPortraitActivity.class);
startActivityForResult(intent, USER_PHOTO_REQUEST_CODE);
}
// 用户头像的预览与裁剪
public void toPreviewUserPhoto(View view) {
Intent intent = new Intent(this, CropUserPhotoActivity.class);
startActivityForResult(intent, CROP_USER_PHOTO_REQUEST_CODE);
}
private Bitmap decodeUriAsBitmap(Uri uri) {
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream(getContentResolver()
.openInputStream(uri));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
return bitmap;
}
}
package com.example.qq.activity.my.user;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import com.example.qq.R;
/**
* Description: 设置用户头像
*
* @author danDingCongRong
* @Version 1.0.0
* @Created at 2014-8-2 20:22:31
* @Modified by [作者] on [修改日期]
*/
public class SetUserHeadPortraitActivity extends Activity {
private static final String TAG = "SetUserHeadPortraitActivity";
private static final int PHOTOGRAPH_REQUEST_CODE = 1;
private static final int ABLUM_REQUEST_CODE = 2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_set_user_head_portrait);
initView();
}
private void initView() {
;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (null == data || Activity.RESULT_CANCELED == resultCode) {
this.finish();
return;
}
// 选择的头像图片所在路径
String fileName = "";
if (PHOTOGRAPH_REQUEST_CODE == requestCode
&& Activity.RESULT_OK == resultCode) {// 拍照和从相册选择
Bundle bundle = data.getExtras();
fileName = selectedUserPhoto(bundle);
} else if (ABLUM_REQUEST_CODE == requestCode) {// 从相册中选择图片
Uri seletedImgUri = data.getData();
fileName = getFileNameFromAblum(seletedImgUri);
}
Intent intent = new Intent(this, UpdateUserPhotoActivity.class);
intent.putExtra("UserPhoto", fileName);
setResult(Activity.RESULT_OK, intent);
this.finish();
}
// 拍照--启动系统相机
public void toPhotograph(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, PHOTOGRAPH_REQUEST_CODE);
}
// 从相册选择--从系统相册中选择图片作为头像
public void toSelectPictureFromAlbum(View view) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_PICK);
intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, ABLUM_REQUEST_CODE);
}
// 取消
public void cancel(View view) {
this.finish();
}
// 使用拍照选择头像图片
private String selectedUserPhoto(Bundle bundle) {
String fileName = "";
if (!Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
Log.i(TAG, "SDCard unmount!");
return fileName;
}
String path = Environment.getExternalStorageDirectory()
+ "/Android/data/com.example.qq/image";
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
FileOutputStream outputStream = null;
try {
fileName = file.getPath() + File.separator + "userPhoto";
outputStream = new FileOutputStream(fileName);
Bitmap bmp = (Bitmap) bundle.get("data");
bmp.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
outputStream.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != outputStream) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}// finally
return fileName;
}
// 从相册获取图片路径
private String getFileNameFromAblum(Uri uri) {
String fileName = "";
if (null == uri) {
return fileName;
}
Uri seletedImgUri = uri;
String[] columns = { MediaStore.Images.Media.DATA };
// 后期可以考虑用线程
Cursor cursor = this.getContentResolver().query(seletedImgUri, columns,
null, null, null);
if (null != cursor && cursor.moveToFirst()) {
int column = cursor.getColumnIndex(columns[0]);
fileName = cursor.getString(column);
}
if (null != cursor && !cursor.isClosed()) {
cursor.close();
}
return fileName;
}
package com.example.qq.activity.my.user;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.view.Window;
import com.example.qq.R;
/**
* Description: 图片裁剪
*
* @author danDingCongRong
* @Version 1.0.0
* @Created at 2014-8-8 14:37:08
* @Modified by [作者] on [修改日期]
*/
public class CropUserPhotoActivity extends Activity {
private static final String TAG = "CropUserPhotoActivity";
private static final int PHOTOGRAPH_REQUEST_CODE = 1;
private static final int ABLUM_REQUEST_CODE = 2;
private static final int CROP_PHOTOGRAPH = 3;
private String path = Environment.getExternalStorageDirectory()
+ "/Android/data/com.example.qq/image/userPhoto.png";
private Uri imageUri = Uri.parse("file://" + path);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_crop_user_photo);
initView();
}
private void initView() {
;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (null == data) {
this.finish();
return;
}
switch (requestCode) {
case PHOTOGRAPH_REQUEST_CODE:
cropImageViewUri(imageUri, 100, 100, CROP_PHOTOGRAPH);
break;
case ABLUM_REQUEST_CODE:
Intent ablumIntent = new Intent(this, UpdateUserPhotoActivity.class);
ablumIntent.putExtra("UserPhotoUri", imageUri);
setResult(Activity.RESULT_OK, ablumIntent);
this.finish();
break;
case CROP_PHOTOGRAPH:
Intent photographIntent = new Intent(this, UpdateUserPhotoActivity.class);
photographIntent.putExtra("UserPhotoUri", imageUri);
setResult(Activity.RESULT_OK, photographIntent);
this.finish();
break;
default:
break;
}
}
public void toPhotograph(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, PHOTOGRAPH_REQUEST_CODE);
}
public void toSelectPictureFromAlbum(View view) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
intent.setType("image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 100);
intent.putExtra("outputY", 100);
intent.putExtra("scale", true);
intent.putExtra("return-data", false);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", false); // no face detection
startActivityForResult(intent, ABLUM_REQUEST_CODE);
}
private void cropImageViewUri(Uri uri, int outputX, int outputY,
int requestCode) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", outputX);
intent.putExtra("outputY", outputY);
intent.putExtra("scale", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
intent.putExtra("return-data", false);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true); // no face detection
startActivityForResult(intent, requestCode);
}
public void cancel(View view) {
this.finish();
}
}