最近项目中用到拍照或者从相册中选择图片并上传的功能,要求上传的图片必须在500k以内,一般手机拍摄的照片在2~4M左右,顾还必须进行图片压缩处理。本文着重讲述如何点击启动照相机,以及如何打开相册选择照片,后续会继续介绍如何进行图片的压缩及上传。


    因为看到的人可能很多,所以要啰嗦两句,以下主要作为个人学习记录,代码从自己的项目中摘得,有些不完整,尚存在不足,仅作参考,如果有更好的方法,欢迎留下牛逼的建议。。



1 启动照相机

这里是用的系统方法启动照相机,查阅资料说需要加入以下权限:



<uses-permission android:name="android.permission.CAMERA" />

不过我没加的时候好像也没什么事 = = ,但还是听话一点好了,接下来用intent来启动照相机,我把照片存储在sd卡中,存储路径可以自定义,当然这里保存的图片是未经压缩的。并且每拍完一次,photo.jpg临时文件就会被替换掉,在相册中可以看得到。以下省略了检测sd卡存不存在啊,获取sd卡路径啊,就不展示了,接着我把路径存在了sharedpreference里面,后面在获取图片时会有用到。


private static final int OPEN_CAMERA = 0;
private void openCamera() {
		Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		File filePath = FileUtil.getSdPath("photo");
		File orgPhoto = new File(filePath, "photo.jpg");
		intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(orgPhoto)); 
		//MediaStore.EXTRA_OUTPUT:设置媒体文件的保存路径;uri.fromFile把路劲转为uri
		getSharedPref().setSharedStr("photoPath", orgPhoto.getAbsolutePath()); //保存一下路径
		startActivityForResult(intent, OPEN_CAMERA); //启动系统拍照页面
	}


2 打开相册选择照片

如下操作打开系统相册,只能选择一张照片

private static final int OPEN_ALBUM = 1;

	private void openAlbum() {
		Intent intent = new Intent(Intent.ACTION_GET_CONTENT);//ACTION_GET_CONTENT ACTION_PICK
		intent.addCategory(Intent.CATEGORY_OPENABLE);
		intent.setDataAndType(MediaStore.Images.Media.INTERNAL_CONTENT_URI,
				"image/*");
		startActivityForResult(intent, OPEN_ALBUM);
	}


3 获取照片

以下是获取照片的方法,在onActivityResult中进行操作,

注:此处获取的Bitmap并没有进行压缩,后续会进行进一步处理

@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode == Activity.RESULT_OK) {
			Bitmap bitmap = null;
			String path = getPreferences(Context.MODE_PRIVATE).getString("photoPath", null);
			switch (requestCode) {
			case OPEN_CAMERA: // 获取刚刚拍完的照片
				bitmap = BitmapFactory.decodeFile(path);
				break;
			case OPEN_ALBUM: //从相册中获取照片
				try {
					Uri photoUri = data.getData();
					ContentResolver cr = this.getContentResolver();
					bitmap = BitmapFactory.decodeStream(cr.openInputStream(photoUri));
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				}
				break;
			default:
				break;
			}
		}
	}


4 照片旋转 
此外,需要注意的是如果是竖着拍照的话,可能获取的bitmap会横过来,解决的方法是读取照片中的角度信息,并把bitmap旋转相应角度即可


/**
	 * 获取照片角度信息
	 * @param path 照片存储路径 
	 * @return 照片旋转角度
	 */
	public static int readPictureDegree(String path) {
		int degree = 0;
		try {
			ExifInterface exifInterface = new ExifInterface(path);
			int orientation = exifInterface.getAttributeInt(
					ExifInterface.TAG_ORIENTATION,
					ExifInterface.ORIENTATION_NORMAL);
			switch (orientation) {
			case ExifInterface.ORIENTATION_ROTATE_90:
				degree = 90;
				break;
			case ExifInterface.ORIENTATION_ROTATE_180:
				degree = 180;
				break;
			case ExifInterface.ORIENTATION_ROTATE_270:
				degree = 270;
				break;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return degree;
	}
/**
	 * 将bitmap做相应的旋转处理
	 * @param bitmap 需要处理的bitmap
	 * @param rotate 旋转角度
	 * @return 旋转完成的bitmap
	 */
	public static Bitmap rotateBitmap(Bitmap bitmap, int rotate) {
		if (bitmap == null)
			return null;
		int w = bitmap.getWidth();
		int h = bitmap.getHeight();
		Matrix mtx = new Matrix();
		mtx.postRotate(rotate);
		return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
	}

以上为两个处理bitmap的工具函数,那么最后在需要操作的地方加入以下代码片,即可完成操作


if (angle != 0) {
		bitmap = BitmapUtil.rotateBitmap(bitmap angle);
	}

因为还是个初程,用的东西比较简单,很多很多都是网上学来的东西,因为也不记得哪里了,就不做一一列举了。。。