通用圖片選擇返回文件路徑並可以使用裁剪

package com.util;

import java.io.File;

import org.androidannotations.annotations.AfterInject;
import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.RootContext;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.provider.MediaStore;
import android.widget.ArrayAdapter;
import android.widget.Toast;

import com.bitcare.patient.util.BitmapUtil.BitMapCallBack;

/**
 * 圖片上傳
 */
@EBean
public class UploadPicture {
	@RootContext
	Context context;
	private Uri photoUri;// 拍攝或選擇的原圖
	private int requestCode;
	private boolean isCrop;// 是否須要裁剪
	private Uri img;// 選擇並裁剪後的圖
	private File fileCrop;// 裁剪後的圖片文件
	private int aspectX; // 裁剪框比例
	private int aspectY; // 裁剪框比例
	private int outputX;// 輸出圖片大小
	private int outputY;// 輸出圖片大小
	private UploadCallBack callback;// 圖片回調
	@Bean
	BitmapUtil bitmapUtil;

	ProgressDialog dialog;

	@AfterInject
	void init() {
		dialog = new ProgressDialog(context);
		dialog.setCancelable(false);
		dialog.setMessage("數據加載中……");
	}

	/**
	 * 回調
	 * @param callBack
	 */
	public void setUploadCallBack(UploadCallBack callBack) {
		this.callback = callBack;
	}

	/**
	 * 上傳原圖(注意預留requestCode)
	 * @param requestCode 拍攝爲n,選擇圖片n+1
	 */
	public void uploadPictue(final int requestCode) {
		bitmapUtil.setCallBack(bitMapCallBack);
		this.requestCode = requestCode;
		isCrop = false;
		new AlertDialog.//
		Builder(context).//
				setAdapter(new ArrayAdapter<String>(context, android.R.layout.simple_dropdown_item_1line, android.R.id.text1, //
						new String[] { "拍攝照片", "選擇圖片" }), //
						new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int which) {
								switch (which) {
								case 0:
									filming(requestCode);
									break;
								case 1:
									choosePhoto(requestCode + 1);
									break;
								}
							}
						}).show();
	}

	/**
	 * 選擇圖片並裁剪(注意預留requestCode)
	 * @param requestCode 拍攝爲n,選擇圖片並裁剪n+1,拍攝裁剪n+2
	 * @param file 裁剪後的圖片文件,文件地址文件能夠爲空
	 * @param aspectX 裁剪框比例
	 * @param aspectY 裁剪框比例
	 * @param outputX 輸出圖片大小
	 * @param outputY 輸出圖片大小
	 */
	public void uploadPictueByCrop(final int requestCode, final File file, final int aspectX, final int aspectY, final int outputX, final int outputY) {
		if (bitmapUtil.checkSd()) {
			bitmapUtil.setCallBack(bitMapCallBack);
			this.requestCode = requestCode;
			isCrop = true;
			this.fileCrop = file;
			if (!this.fileCrop.getParentFile().exists()) {
				this.fileCrop.getParentFile().mkdirs();
			}
			this.aspectX = aspectX;
			this.aspectY = aspectY;
			this.outputX = outputX;
			this.outputY = outputY;
			new AlertDialog.//
			Builder(context).//
					setAdapter(new ArrayAdapter<String>(context, android.R.layout.simple_dropdown_item_1line, android.R.id.text1, //
							new String[] { "拍攝照片", "選擇圖片" }), //
							new DialogInterface.OnClickListener() {
								@Override
								public void onClick(DialogInterface dialog, int which) {
									switch (which) {
									case 0:
										filming(requestCode);
										break;
									case 1:
										choosePhotoByCrop(requestCode + 1, aspectX, aspectY, outputX, outputY);
										break;
									}
								}
							}).show();
		} else {
			Toast.makeText(context, "內存卡不存在", Toast.LENGTH_SHORT).show();
		}
	}

	/**
	 * 返回結果
	 * @param requestCode
	 * @param resultCode
	 * @param data
	 */
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		String filePath = null;
		if (resultCode == Activity.RESULT_OK) {
			if (this.requestCode == requestCode) {// 拍攝的圖片
				dialog.show();
				filePath = CommUtil.getImageAbsolutePath((Activity) context, photoUri);
				bitmapUtil.rotateBitmapDegree(requestCode, filePath);
			} else if (this.requestCode + 1 == requestCode) {// 選擇的圖片或裁剪
				if (!isCrop) {// 選擇原圖
					if (data == null || data.getData() == null) {
						Toast.makeText(context, "選擇圖片文件出錯", Toast.LENGTH_SHORT).show();
					} else {
						photoUri = data.getData();
						filePath = CommUtil.getImageAbsolutePath((Activity) context, photoUri);
					}
				} else {// 裁剪的圖
					filePath = CommUtil.getImageAbsolutePath((Activity) context, img);
				}
				if (StringUtil.isNotTrimBlank(filePath)) {
					dialog.show();
					bitmapUtil.rotateBitmapDegree(requestCode, filePath);
				} else {
					Toast.makeText(context, "選擇圖片文件出錯", Toast.LENGTH_SHORT).show();
				}
			} else if (this.requestCode + 2 == requestCode) {// 拍攝並裁剪的圖
				filePath = CommUtil.getImageAbsolutePath((Activity) context, img);
				if (StringUtil.isNotTrimBlank(filePath)) {
					dialog.show();
					bitmapUtil.rotateBitmapDegree(requestCode, filePath);
				} else {
					Toast.makeText(context, "選擇圖片文件出錯", Toast.LENGTH_SHORT).show();
				}
			}
		}
	}

	public interface UploadCallBack {
		void callback(int requestCode, String filePath);
	}

	/* —————————————————————————————————————————————————————————— */
	private BitMapCallBack bitMapCallBack = new BitMapCallBack() {
		@Override
		public void callBack(int requestCode, String path) {
			dialog.dismiss();
			// 拍攝的圖片
			if (UploadPicture.this.requestCode == requestCode) {
				if (isCrop) {// 須要裁剪
					photoUri = Uri.fromFile(new File(path));
					cropPhoto(requestCode + 2, aspectX, aspectY, outputX, outputY);
				}
			} else {
				if (callback != null) {
					callback.callback(requestCode, path);
				}
			}
		}
	};

	/**
	 * 拍攝圖片
	 * @param requestCode
	 */
	private void filming(int requestCode) {
		// 拍照
		// 執行拍照前,應該先判斷SD卡是否存在
		if (bitmapUtil.checkSd()) {
			Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
			/***
			 * 須要說明一下,如下操做使用照相機拍照,拍照後的圖片會存放在相冊中的 這裏使用的這種方式有一個好處就是獲取的圖片是拍照後的原圖
			 * 若是不實用ContentValues存放照片路徑的話 ,拍照後獲取的圖片爲縮略圖不清晰
			 */
			photoUri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new ContentValues());
			intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, photoUri);
			if (context instanceof Activity) {
				((Activity) context).startActivityForResult(intent, requestCode);
			} else {
				Toast.makeText(context, "不能使用非Activity的子類", Toast.LENGTH_SHORT).show();
			}
		} else {
			Toast.makeText(context, "內存卡不存在", Toast.LENGTH_SHORT).show();
		}
	}

	/**
	 * 選擇圖片
	 * @param requestCode
	 */
	private void choosePhoto(int requestCode) {
		// 選擇圖庫
		Intent intent = new Intent();
		intent.setType("image/*");
		intent.setAction(Intent.ACTION_GET_CONTENT);
		intent.addCategory(Intent.CATEGORY_OPENABLE);
		if (context instanceof Activity) {
			((Activity) context).startActivityForResult(intent, requestCode);
		} else {
			Toast.makeText(context, "不能使用非Activity的子類", Toast.LENGTH_SHORT).show();
		}
	}

	/**
	 * 選擇圖片並裁剪保存
	 * @param requestCode
	 * @param file 文件地址(必須有此文件)
	 * @param aspectX 裁剪框比例
	 * @param aspectY 裁剪框比例
	 * @param outputX 輸出圖片大小
	 * @param outputY 輸出圖片大小
	 */
	private void choosePhotoByCrop(int requestCode, int aspectX, int aspectY, int outputX, int outputY) {
		img = Uri.fromFile(fileCrop);
		Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null);
		intent.setType("image/*");
		intent.putExtra("crop", "true");
		intent.putExtra("aspectX", aspectX);// 裁剪框比例
		intent.putExtra("aspectY", aspectY);
		intent.putExtra("outputX", outputX);// 輸出圖片大小
		intent.putExtra("outputY", outputY);
		intent.putExtra("scale", true);// 若是選擇的圖小於裁剪大小則進行放大
		intent.putExtra("scaleUpIfNeeded", true);// 若是選擇的圖小於裁剪大小則進行放大
		intent.putExtra("return-data", false);// 是否輸出bitmap
		intent.putExtra(MediaStore.EXTRA_OUTPUT, img);// 須要直接輸出到文件的URI
		intent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.toString());// 輸出格式
		if (context instanceof Activity) {
			((Activity) context).startActivityForResult(intent, requestCode);
		} else {
			Toast.makeText(context, "不能使用非Activity的子類", Toast.LENGTH_SHORT).show();
		}
		// 大圖能夠考慮直接寫入文件而不返回bitmap
	}

	/**
	 * 裁剪拍攝出來的圖片
	 * @param requestCode
	 * @param file 文件地址(必須有此文件)
	 * @param aspectX 裁剪框比例
	 * @param aspectY 裁剪框比例
	 * @param outputX 輸出圖片大小
	 * @param outputY 輸出圖片大小
	 */
	private void cropPhoto(int requestCode, int aspectX, int aspectY, int outputX, int outputY) {
		img = Uri.fromFile(fileCrop);
		Intent intent = new Intent("com.android.camera.action.CROP");
		intent.setDataAndType(photoUri, "image/*");
		intent.putExtra("crop", "true");
		intent.putExtra("aspectX", aspectX);
		intent.putExtra("aspectY", aspectY);
		intent.putExtra("outputX", outputX);
		intent.putExtra("outputY", outputY);
		intent.putExtra("scale", true);// 若是選擇的圖小於裁剪大小則進行放大
		intent.putExtra("scaleUpIfNeeded", true);// 若是選擇的圖小於裁剪大小則進行放大
		intent.putExtra(MediaStore.EXTRA_OUTPUT, img);
		intent.putExtra("return-data", false);
		intent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.toString());
		intent.putExtra("noFaceDetection", true); // no face detection
		((Activity) context).startActivityForResult(intent, requestCode);
	}
}
使用方法
 
UploadPicture uploadPicture = new UploadPicture();
uploadPicture.setUploadCallBack(uploadCallBack);
//彈出選擇圖片
uploadPicture.uploadPictue(REQUEST_UPLOAD_BY_PICTURE);
//或者裁剪
uploadPicture.uploadPictueByCrop(REQUEST_UPLOAD_BY_PICTURE, 裁剪後保存的文件,裁剪框X, 裁剪框Y, 輸出圖片寬度, 輸出圖片高度);

在activity中的onActivityResult中加上
uploadPicture.onActivityResult(requestCode, resultCode, data);

最後在回調中得到文件路徑
UploadCallBack uploadCallBack = new UploadCallBack() {
	@Override
	public void callback(final int requestCode, final String filePath) {
	}
}

版權聲明:本文爲博主原創文章,未經博主容許不得轉載。java

相關文章
相關標籤/搜索