【Android】使用系统相机或者从相册中获取图片资源并进行适当裁剪

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();
	}

}












  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值