從圖庫中選擇圖片或拍照選擇图片对话框实现总结

项目中经常遇到从图库选择或从相机拍照的图片选择对话框的需求,这里做一个总结,方便以后参考使用。

代码片段是从一个完整项目截取部分。


1.先判斷手機是否有SD卡,若沒有彈出提示框

Boolean isSDPresent = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
    	if (!isSDPresent){
    		AlertDialog.Builder builder = new AlertDialog.Builder(this);
    		
    		builder.setTitle(getString(R.string.exit_dialog));
    		builder.setIcon(android.R.drawable.ic_dialog_alert);
    		builder.setMessage(getText(R.string.error_no_sdcard));
    		builder.setCancelable(false);
    		builder.setPositiveButton(getText(R.string.btn_yes), new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int which) {
					if (dlgNoSDCard != null) {
						dlgNoSDCard.dismiss();
						dlgNoSDCard = null;
					}
				}
			});
    		if (dlgNoSDCard == null) {
    			dlgNoSDCard = builder.create();
    		}
    		dlgNoSDCard.show();
    		return;
    	}

2.定義選擇圖片的Uri文件路徑,用來保存選擇的圖片,從相機選擇返回的是Uri的形式的圖片

Uri mImageCaptureUri = null;
customizedFilePath();
private Uri customizedFilePath() {
     //目錄名
    	String sDirName = "psmd/1touchmore/photo";
    //文件名
    	String fileName = System.currentTimeMillis() + ".jpg";
    //SD卡目錄
    	File sdDir = Environment.getExternalStorageDirectory();
    //生成目錄
    	File theDir = new File(sdDir, sDirName);
        if (!theDir.exists()) {
            theDir.mkdirs();
        }
     //生成文件
     File picFile = new File(theDir, fileName);
//返回文件路徑對應的Uri對象
     mImageCaptureUri = Uri.fromFile(picFile);
     return mImageCaptureUri;
    }


3.從系統圖庫選擇:

Intent pickPhoto = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
pickPhoto.setType("image/*");
//可裁剪
pickPhoto.putExtra("crop", "true");
//輸出格式
pickPhoto.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
//不需要人臉檢測
pickPhoto.putExtra("noFaceDetection", true);
// outputX,outputY 是剪裁图片的宽高
pickPhoto.putExtra("outputX", reqWidth);
pickPhoto.putExtra("outputY", reqHeight);
//aspectX aspectY 是宽高的比例
pickPhoto.putExtra("aspectX", 1);  
pickPhoto.putExtra("aspectY", 1);
//縮放比例
pickPhoto.putExtra("scale", 1);
pickPhoto.putExtra("return-data", true);
try {
	 startActivityForResult(pickPhoto, TAKE_FROM_GALLERY);
	}
	catch (ActivityNotFoundException localActivityNotFoundException)
	{
		Log.d("Light", "Pick From Gallery Activity Not Found => " + pickPhoto.getAction());
	}

4.從相機拍照:

Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePicture.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// 指定调用相机拍照后照片的储存路径
takePicture.putExtra(MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
takePicture.putExtra("return-data", true);
try{
		startActivityForResult(takePicture, TAKE_FROM_CAMERA); 		
	 }
catch (ActivityNotFoundException e) {
		Log.d("Light", "Take Pict Activity Not Found => " + takePicture.getAction());
	 }


5.在onActivityResult方法中判斷返回的request code分別處理

 switch(requestCode) {
			case TAKE_FROM_GALLERY:
               //從圖庫選擇的圖片返回
               try {
	            	Bundle extras = data.getExtras();
	            	if(extras != null ) { 
//返回的裁剪后的圖片的bitmap
                    	bmpOriginal = extras.getParcelable("data");
                    	Runnable r = new Runnable(){
                    		public void run(){
                                //重新定義寬和高設置到View
                    			bmpLarge = getResizedBitmapToNewWH(bmpOriginal, bmpOriginal.getWidth(), bmpOriginal.getHeight());
                    			ivChooseHeaderIcon.setImageBitmap(bmpLarge);
                    		}
                    	};
                    	ivChooseHeaderIcon.post(r);
                    }
	            }
		        catch(Exception e)
		        {
		            Log.e("Could not save", e.toString());
		        }

private Bitmap getResizedBitmapToNewWH(Bitmap bm, int newWidth, int newHeight) {
	        int width = bm.getWidth();
	        int height = bm.getHeight();

	        float aspect = (float)width / height;
	        float scaleWidth = newWidth;
	        float scaleHeight = scaleWidth / aspect;

	        Bitmap resizedBitmap = null;
	        
	        // create a matrix for the manipulation
	        Matrix matrix = new Matrix();

	        // resize the bit map
	        matrix.postScale(scaleWidth / width, scaleHeight / height);

	        resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
	        try {
	        	if ((resizedBitmap.getHeight() - newHeight) >= 0) {
	                resizedBitmap = Bitmap.createBitmap(resizedBitmap, 0, (resizedBitmap.getHeight() - newHeight) / 2, newWidth, newHeight);
	        	}
	        } catch (Exception e) {
	        	Log.d("Light", e.toString());
	        }
	        return resizedBitmap;
	    }
case TAKE_FROM_CAMERA:
//從相機拍照返回的圖片調用裁剪
	  Intent cropIntent = new Intent("com.android.camera.action.CROP");

		cropIntent.setDataAndType(mImageCaptureUri, "image/*");
cropIntent.putExtra("crop", "true");
		cropIntent.putExtra("aspectX", 1);
		cropIntent.putExtra("aspectY", 1);
		cropIntent.putExtra("outputX", reqWidth);
		cropIntent.putExtra("outputY", reqHeight);
		cropIntent.putExtra("return-data", true);
		cropIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
		cropIntent.putExtra("noFaceDetection", true);
		try{
			startActivityForResult(cropIntent, TAKE_FROM_CROP);
		}
		catch (ActivityNotFoundException e)
		{
			Log.d("Light", "Cannot Call Crop Activity => " + cropIntent.getAction());
		}
case TAKE_FROM_CROP:
       //裁剪后的圖片 設置到View
       Bundle extras = data.getExtras();
            if(extras != null ) { 
                try {
                    	bmpOriginal = extras.getParcelable("data");
    		    		Runnable r = new Runnable(){
    		    			public void  run(){
    					    bmpLarge = getResizedBitmapToNewWH(bmpOriginal, bmpOriginal.getWidth(), bmpOriginal.getHeight());
    					    ivChooseHeaderIcon.setImageBitmap(bmpLarge);
    		    			}
    		    		};
    		    		    ivChooseHeaderIcon.post(r);
                	}
    		        catch(Exception e)
    		        {
    		            Log.e("Could not save", e.toString());
    		        }
                }


6.當保存數據時,保存選擇的圖片路徑

private void doSavePic(){
		FileOutputStream stream;
		//從圖庫和相機選擇圖片會返回bitmap對象 
		if (bmpOriginal != null)
		{
			String sLargePicPath = "";
			try {
				if (mImageCaptureUri != null) {
					// 若不為 null,則代表是拍照片
					sLargePicPath = mImageCaptureUri.getPath();
				}
				else {
					// 取得存放照片的路徑名 - 大張
					sLargePicPath = customizedFilePath().getPath();
				}
				stream = new FileOutputStream(sLargePicPath);
				// 將圖檔縮小成 700 x 400 的規格 
				bmpTemp = getResizedBitmapToNewWH(bmpOriginal, 700, 400);
				// 不做壓縮,直接存
				bmpTemp.compress(CompressFormat.JPEG, 100, stream);
				stream.flush();
				stream.close();
				// 取得存放照片的路徑名 - 小張 
				String sSmallPicPath = sLargePicPath.substring(0, sLargePicPath.indexOf(".")) + "_small.jpg";
				// 將變小後的圖形回存到 SD 上
				stream = new FileOutputStream(sSmallPicPath);
				// 把圖型轉成小張
				bmpTemp = getResizedBitmapToSquare(bmpOriginal, 200);
			
				//壓縮比改為 90
				bmpTemp.compress(CompressFormat.JPEG, 90, stream);
				stream.flush();
				stream.close();
				// 將要存的檔案名稱,設定給 ImagePathFile
				ImagePathFile = sSmallPicPath;
				
				// 釋放 BMP 所佔的資源
				bmpOriginal.recycle();
				bmpTemp.recycle();
			} catch (Exception e) {
	            Log.e("Could not save => ", e.toString());
			}
		} 
	}




原文地址:https://www.cnblogs.com/krislight1105/p/3748326.html