项目中经常遇到从图库选择或从相机拍照的图片选择对话框的需求,这里做一个总结,方便以后参考使用。
代码片段是从一个完整项目截取部分。
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; }
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()); }
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()); } }
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()); } } }