1. 程式人生 > >Android相機預覽方向

Android相機預覽方向

 以前對Camera瞭解的不是太深入,最近有需求把人臉識別 整合到專案,必然會與Camera打交道,遇到一些坑,與大家分享一下。

一、預覽方向

  Camera.CameraInfo info = new Camera.CameraInfo();

  首先理解一下 info.orientation  官方解釋

官方定義:orientation表示相機影象的方向。它的值是相機影象順時針旋轉到裝置自然方向一致時的角度。例如假設裝置是豎屏的。後置相機感測器是橫屏安裝的。當你面向螢幕時,如果後置相機感測器頂邊的和裝置自然方向的右邊是平行的,則後置相機的orientation90。如果前置相機感測器頂邊和裝置自然方向的右邊是平行的,則前置相機的

orientation270

畫了一個簡單的草圖,我用兩部手機進行測試,一部是華為榮耀6plus 、另一個是定做的 T6A,測試的時候把手機固定為了豎屏應用


另一款Android 機 T6A,攝像頭位置比較特別,我獲取的info.orientation = 0; 那意味著我不用旋轉,捕獲的資料,都是與螢幕方向一致的

特別說明:

對於後置相機,只需要旋轉後置相機的orientation 90即可和螢幕方向保持一致;

對於前置相機的預覽方向,相機預覽的影象是相機採集到的影象的映象,由於系統對前置相機採集到的影象做了映象,因此需要旋轉 270-180,也是90度才可與螢幕方向保持一致

setDisplayOrientation(int degrees)

這個API修改的僅僅是Camera的預覽方向而已,並不會影響到PreviewCallback回撥、生成的JPEG圖片和錄影檔案的方向,這些資料的方向依然會跟影象Sensor的方向一致。


二、官方推薦預覽方向寫法


呼叫this.getWindowManager().getDefaultDisplay().getRotation();

該函式的返回值,有如下四種:

Surface.ROTATION_0,Surface.ROTATION_90,Surface.ROTATION_180,Surface.ROTATION_270

其中,Surface.ROTATION_0 表示的是手機豎屏方向向上,後面幾個以此為基準依次以順時針90度遞增。


三 、拍照方向

Camera的拍照方向:當你點選拍照按鈕,得到的圖片方向不一定與畫面中預覽的方向一致,這是因為拍攝的照片是將影象Sensor採集到的資料直接儲存到SDCard上的,因此,Camera的拍照方向與上述的Camera的採集影象方向一致。

第一種做法 

rotation 可由上面獲取的預覽方向獲取,注意前置攝像頭要翻轉180度。

 parameters.setRotation(rotation);//設定rotation旋轉角度到Camera的引數parameters。這個旋轉角度最後會寫到exif資訊中去 。

第二種做法 

 通過ExifInterface,去獲取圖片Orientation方向 ,然後旋轉合適的角度,去展示

1、讀取圖片的旋轉屬性

/**
 * 讀取圖片的旋轉的角度
 *
 * @param path
 *            圖片絕對路徑
 * @return 圖片的旋轉角度
 */
public int getBitmapDegree(String path) {
    int degree = 0;
    try {
        // 從指定路徑下讀取圖片,並獲取其EXIF資訊
        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;
}
2、將圖片按照某個角度進行旋轉

/**
 * 將圖片按照某個角度進行旋轉
 *
 * @param bm
 *            需要旋轉的圖片
 * @param degree
 *            旋轉角度
 * @return 旋轉後的圖片
 */
public Bitmap rotateBitmapByDegree(Bitmap bm, int degree) {
    Bitmap returnBm = null;
  
    // 根據旋轉角度,生成旋轉矩陣
    Matrix matrix = new Matrix();
    matrix.postRotate(degree);
    try {
        // 將原始圖片按照旋轉矩陣進行旋轉,並得到新的圖片
        returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
    } catch (OutOfMemoryError e) {
    }
    if (returnBm == null) {
        returnBm = bm;
    }
    if (bm != returnBm) {
        bm.recycle();
    }
    return returnBm;
}