版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_29078329/article/details/78142158
最近项目中用到了用户上传头像,需要支持相机拍照、相册选取图片,并裁剪的功能,下面记录整理一下实现过程,先上图:
一、手机拍照获取图片
指定图片路径mCameraFile,启动相机拍照,拍摄的图片会保存在mCameraFile中:
private void selectFromCamera() {
Uri outputFileUri = Uri.fromFile(mCameraFile);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
mActivity.startActivityForResult(intent, 1002);
}
mCameraFile的获取:
/**
* 拍照图片保存的路径
*
* @return
*/
public static File createImageFile() {
File appDir = new File(Environment.getExternalStorageDirectory(), "topNews");
if (!appDir.exists()) {
appDir.mkdir();
}
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");//设置以当前时间格式为图片名称
String fileName = df.format(new Date()) + ".jpeg";
File file = new File(appDir, fileName);
return file;
}
二、onActivityResult(int requestCode, int resultCode, Intent data)中获取拍摄的图片
private void handleCameraResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
Uri fileUri = FileUtils.getImageContentUri(this, mCameraFile);
String imgPath = FileUtils.getImagePathWithUri(this, fileUri, null);
Bitmap bitmap = ImageZip.decodeSampledBitmapFromFile(mFile.getAbsolutePath(),mWidth, mHeight);
}
}
//根据图片对应的File,拿到图片的URI
public static Uri getImageContentUri(Context context, java.io.File imageFile) {
String filePath = imageFile.getAbsolutePath();
Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Images.Media._ID}, MediaStore.Images.Media.DATA + "=? ",
new String[]{filePath}, null);
if (cursor != null && cursor.moveToFirst()) {
int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));
Uri baseUri = Uri.parse("content://media/external/images/media");
return Uri.withAppendedPath(baseUri, "" + id);
} else {
if (imageFile.exists()) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, filePath);
return context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} else {
return null;
}
}
}
//根据图片的URI,得到图片File的路径
public static String getImagePathWithUri(Context context, Uri uri, String selection) {
String path = null;
Cursor cursor = context.getContentResolver().query(uri, null, selection, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
}
cursor.close();
}
return path;
}
//采样压缩,预防oom
public static Bitmap decodeSampledBitmapFromFile(String pathName, int reqWidth, int reqHeight) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(pathName, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds = false;
Bitmap src = BitmapFactory.decodeFile(pathName, options);
return src;
}
private static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth, int reqHeight) {
// 源图片的高度和宽度
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
while ((halfHeight / inSampleSize) > reqHeight || (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
注意在获取bitmap时,如果imagView要加载该bitmap,要对图片进行相应的压缩,防止在大图片的情况下发生OOM。
三、从相册中选取图片
private void selectFromAlbumSingle() {
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
mActivity.startActivityForResult(intent, 1001);
}
四、onActivityResult(int requestCode, int resultCode, Intent data)中获取选中的图片
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1001) {
Uri uri = data.getData();
}
}
得到uri后,获取bitmap和相机拍照一样:
五、裁剪图片
指定裁剪图片保存的路径mCropFile,启动系统裁剪程序进行裁剪,完成后,图片会保存在mCropFile中。
/**
* 裁剪图片
*
* @param uri
*/
public void cutPic(Uri uri) {
Intent intent = new Intent("com.android.camera.action.CROP");
mCropFile = FileUtils.createImageFile();
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
// aspectX aspectY 是宽高的比例
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
// outputX outputY 是裁剪图片宽高
intent.putExtra("outputX", 300);
intent.putExtra("outputY", 300);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mCropFile));
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true);
intent.putExtra("return-data", false);
startActivityForResult(intent, 1010);
}
六、获取裁剪图片
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//裁剪图片
if (requestCode == 1010) {
handleCutPicResult(resultCode);
}
}
private void handleCutPicResult(int resultCode) {
if (resultCode == RESULT_OK) {
String portraitPath = mCropFile.getAbsolutePath();
Bitmap bitmap = BitmapFactory.decodeFile(portraitPath);
mPortraitImg.setImageBitmap(bitmap);
}
}
参考:http://blog.csdn.net/gdutxiaoxu/article/details/53411790