1. 程式人生 > >自定義相機那些坑之預覽介面適配及原理

自定義相機那些坑之預覽介面適配及原理

0.思維導圖

1.問題的產生

當Activity的oritation設定為portrait時,前置/後置攝像頭預覽影象會逆時針旋轉90度展示,如圖:

2.問題產生的本質

相機影象資料來自影象感應器(物理器件)(Image Sensor),影象感應器再將資料輸出到預覽Window上時,影象感應器有一個讀取影象的方向,並且不會改變。這個讀取的方向通過CameraInfo的orientation可以獲取。現在的影象感應器硬體的讀取方向都是順時針90度,即讀取方向如下圖:

由此就會產生預覽方向逆時針旋轉90度。具體的產生過程如圖:

3.官方推薦的解決方案

    public static void setCameraDisplayOrientation(Activity activity,
          int cameraId, android.hardware.Camera camera) {
      android.hardware.Camera.CameraInfo info =
              new android.hardware.Camera.CameraInfo();
      android.hardware.Camera.getCameraInfo(cameraId, info);
      int rotation = activity.getWindowManager().getDefaultDisplay()
              .getRotation();
      int degrees = 0;
      switch (rotation) {
         case Surface.ROTATION_0: degrees = 0; break;
          case Surface.ROTATION_90: degrees = 90; break;
          case Surface.ROTATION_180: degrees = 180; break;
          case Surface.ROTATION_270: degrees = 270; break;
      }

     int result;
      if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
          result = (info.orientation + degrees) % 360;
          result = (360 - result) % 360;  // compensate the mirror
     } else {  // back-facing
         result = (info.orientation - degrees + 360) % 360;
     }
      camera.setDisplayOrientation(result);
  }

推薦的解決方案中:
(1)CameraInfo是例項化的相機類,其中orientation是相機(影象感應器)相對於自然座標系(即左上角座標系)的旋轉角度數.
(2)rotation是預覽window的旋轉的方向,當Activity的 screenOrientation="portrait"時,rotation=0,也就是沒有旋轉,當 screenOrientation="landscape"時,rotation=1。
(3)camera.setDisplayOrientation(int param)根據官方解釋就是圖片已經輸出後旋轉的度數。旋轉值可以是 0, 90, 180, and 270. (a)當開啟後置攝像頭,Window豎屏顯示時,預覽影象旋轉: result=(90-0+360)%360=90,順時針旋轉90度.
(b)當開啟後置攝像頭,Window橫屏顯示時,預覽影象旋轉: result=(90-90+360)%360=0,順時針旋轉0度.
(c)前置攝像頭有一些特殊情況,在下面會談到。
(d)param的引數官方解釋 @param degrees the angle that the picture will be rotated clockwise.Valid values are 0, 90, 180, and 270.

4.一些存在的問題

1、對於前後攝像頭,影象感應器輸出的方向是一致的,並不像部分部落格所說進行了映象。
2、CameraInfo中的facing欄位,無論是呼叫前置攝像頭還是後置攝像頭,facing均為0,即後置攝像頭值。如下圖各種機型返回值:

5.參考相關文件

騰訊Bugly: https://blog.csdn.net/Tencent_Bugly/article/details/53375311 http://hao.caibaojian.com/16047.html
Demo: https://github.com/xionglei12/camera-preview-demo.git