天天看點

安卓進階6 拍照或者從相冊擷取圖檔 并檢測旋轉角度或者更新畫冊掃描

1. 旋轉角度

當我們從手機讀取圖檔時候發現其圖檔旋轉了90或者其他度數,比如三星拍照後的照片就是個例子.這時候我們讀取出來判斷角度然後在逆向回轉為正向的圖檔
  1. 所需類 ExifInterface

    Exif是 Exchangeable Image File 縮寫

/**
     * 讀取圖檔屬性:旋轉的角度
     * 
     * @param path 圖檔絕對路徑
     * @return degree 旋轉角度
     */
    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;
    }           
/**
     * 旋轉圖檔
     * 
     * @param angle 旋轉角度
     * @param bitmap 原圖
     * @return bitmap 旋轉後的圖檔
     */
    public static Bitmap rotateImage(int angle, Bitmap bitmap) {
        // 圖檔旋轉矩陣
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
        // 得到旋轉後的圖檔
        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
                bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        return resizedBitmap;
    }           

2. 調用系統的剪切圖檔軟體

當我們某個圖檔過大 想讓使用者自行選擇剪切區域
  1. 意圖Intent的action “com.android.camera.action.CROP”
  2. 意圖Intent的data類型 檔案位址Uri 如Uri.fromFile(new File(fileSrc))
  3. 意圖intent的type類型(mime) “image/*”
以下是可以傳入到intent的數值 (putExtra)
數值名(字元串類型) 傳入值類型 作用 案例
crop String 設定true才能出剪輯的小方框,不然沒有剪輯功能,隻能選取圖檔 intent.putExtra(“crop”, “true”);
aspectX int 放大縮小比例的X intent.putExtra(“aspectX”, 1);
aspectY 放大縮小比例的Y intent.putExtra(“aspectY”, 1);
outputX //這個是限制輸出圖檔x方向大小(最大限制) intent.putExtra(“outputX”, 320);
outputY //這個是限制輸出圖檔y方向大小(最大限制) intent.putExtra(“outputY”, 320);
return-data boolean 是否傳回資料圖(後面有案例) intent.putExtra(“return-data”, true);
scale和scaleUpIfNeeded 切圖大小不足輸出,邊緣出現類似毛邊或者鋸齒等 innerIntent.putExtra(“scale”, true);innerIntent.putExtra(“scaleUpIfNeeded”, true);
/***
     * 裁剪圖檔
     * @param activity Activity
     * @param uri 圖檔的Uri
     */
    public static void cropPicture(Activity activity, Uri uri) {
        Intent innerIntent = new Intent("com.android.camera.action.CROP");
        innerIntent.setDataAndType(uri, "image/*");
        innerIntent.putExtra("crop", "true");// 設定true才能出剪輯的小方框,不然沒有剪輯功能,隻能選取圖檔
        innerIntent.putExtra("aspectX", 1); // 放大縮小比例的X
        innerIntent.putExtra("aspectY", 1);// 放大縮小比例的X   這裡的比例為:   1:1
        innerIntent.putExtra("outputX", 320);  //這個是限制輸出圖檔大小
        innerIntent.putExtra("outputY", 320); 
        innerIntent.putExtra("return-data", true);
        // 切圖大小不足輸出,無黑框
        innerIntent.putExtra("scale", true);
        innerIntent.putExtra("scaleUpIfNeeded", true);
        File imageFile = new File(getImagePath(activity.getApplicationContext()));
        innerIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imageFile));
        innerIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        activity.startActivityForResult(innerIntent, REQUEST_CROP_IMAGE);
    }



           
//回調:activityforresult
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data){
// 擷取傳回資料
Bitmap bmp = data.getParcelableExtra("data");

}           

3. 拍照擷取圖檔

  1. intent 的action: MediaStore.ACTION_IMAGE_CAPTURE

    直接案例:

// 設定相機拍照後照片儲存路徑
            File mPictureFile = new File(Environment.getExternalStorageDirectory(), 
                    "picture" + System.currentTimeMillis()/1000 + ".jpg");
            // 啟動拍照,并儲存到臨時檔案
            Intent mIntent = new Intent();
            mIntent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
            mIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mPictureFile));
            mIntent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);

            startActivityForResult(mIntent, REQUEST_CAMERA_IMAGE);           

回調acativityforesult

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != RESULT_OK) {
            return;
        }

if (!mPictureFile.exists()) {
                showTip("拍照失敗,請重試");
                return;
            }

            fileSrc = mPictureFile.getAbsolutePath();

}
           

4.更新畫冊

private void updateGallery(String filename) {
        MediaScannerConnection.scanFile(this, new String[] {filename}, null,
                new MediaScannerConnection.OnScanCompletedListener() {

                    @Override
                    public void onScanCompleted(String path, Uri uri) {

                    }
                });
    }           

5.從手機相冊擷取

Intent intent = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_PICK);
            startActivityForResult(intent, REQUEST_PICTURE_CHOOSE);           
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != RESULT_OK) {
            return;
        }
if ("file".equals(data.getData().getScheme())) {
                // 有些低版本機型傳回的Uri模式為file
                fileSrc = data.getData().getPath();
            } else {
                // Uri模型為content
                //選擇資料位址字段
                String[] proj = {MediaStore.Images.Media.DATA};
                Cursor cursor = getContentResolver().query(data.getData(), proj,
                        null, null, null);
                cursor.moveToFirst();
                //擷取字段在第幾列
                int idx = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                //擷取所在位址
                fileSrc = cursor.getString(idx);
                cursor.close();
            }

}