Android Camera的進化史

Part1: Camera1(Android的傻瓜機)

  • Camera1 的開發中,打開相機,設置參數的過程是同步的,就跟用戶實際使用camera的操做步驟同樣。可是若是有耗時狀況發生時,會致使整個調用線程等待;
  • 開發者若是想要個性化設置camera效果,沒法手動設置調整參數,須要依靠第三方算法對於回調的數據進行處理(NV21)。並且不一樣手機的回調數據效果都是不同的,採用第三方算法調整,一般效果很差;
  • 開發者所能獲取的Camera狀態信息有限;
camera1 的開發過程比較簡單,對於常規視頻採集,若是隻要通常的預覽功能,是沒問題的,然而若是想要挖掘Camera更多的功能,camera1沒法知足,因而有了camera2.

Part2: Camera2(Android的單反)

  • Camera2 的開發中,camera的生命週期都是異步的,即發送請求,等待回調的client-service模式;
  • 系統: Android L+;
  • 這裏的關鍵回調主要是三個:
(1)CameraDevice.StateCallback ///好比線程A發送打開相機請求, 線程B中收到相機狀態回調,線程B中與cameraDevice創建會話,設置參數,數據回調處理;
(2)CameraCaptureSession.StateCallback ///與CameraDevice創建會話後,收到的會話狀態回調;
(3)ImageReader.OnImageAvailableListener // 開發者能夠直接獲取而且操做的數據回調;
  • 經過跟相機創建的會話,能夠更加精細的調整Camera參數:好比ISO感光度,曝光時間,曝光補償……;
  • 若是開發者想要更多本身的定製,也能夠直接使用回調數據(YUV488);
  • MultiCamera的支持;

Multi-Camera 的支持:

  • 系統:Android P+;
  • 目前支持的multi-camera的設備: Pixel 3, mate20 系列;
  • Multi-Camera 新功能:
(1)更好的光學變焦:以前的方式一般使用數碼變焦或者是單個攝像頭的光學變焦來達到變焦的效果, 經過多攝像頭的變焦方式,不管遠景仍是近景,均可以採到更好質量的數據。
(2)景深計算:經過多攝像頭的景深不一樣,能夠獲得每一幀圖片中不一樣物體的景深,從而更好的區分前景或者後景。應用範圍:背景虛化,背景替換,現實加強。
(3)更廣的視角:更廣的視角帶來魚眼鏡頭的畸變效果,畸變矯正功能。 CaptureRequest.DISTORTION_CORRECTION_MODE
(4)人臉識別功能:跟畸變效果同樣,自帶人臉識別功能。應用範圍:人臉裁剪,人臉特效。 CaptureResult.STATISTICS_FACE_DETECT_MODE
(5)多路流同時採集:場景包括(單攝像頭輸出多流,多攝像頭輸出多流) normalOutputConfigImageReader.setPhysicalCameraId(normalLensId) wideOutputConfigImageReader.setPhysicalCameraId(wideAngleId) params.previewBuilder?.addTarget(normalSurface) params.previewBuilder?.addTarget(wideSurface)
  • 帶來的問題:更耗內存,更耗電
  • 趨勢:單個手機中,支持更多的攝像頭
Camera2 雖然給開發者帶來了相機的更多可玩性,然而android的碎片化,致使不少設備的兼容性問題頻繁發生。尤爲國內的手機廠商,對camera2 的支持程度各不相同,
因此Camera2的開發難度更多的是在兼容性,因而有了CameraX。

Part3: CameraX(Android的個性化相機)

  • 系統:Android L+
  • Jetpack 內的一套Camera開發支持庫。
  • 特色:
  1. 更簡單易用的API,更少的代碼量,使開發者更專一業務的個性化實現。好比:對採集到圖片作分析處理。
  2. 更好的兼容性,減小不一樣設備適配煩惱:包括寬高比、屏幕方向、旋轉、預覽大小和高分辨率圖片大小。
  3. 數據分析: 開發者依然能夠對數據進行個性化處理。
  4. 第三方Camera特效拓展:對於一些手機廠商特定實現的camera特效,開發者也可使用。
  5. Code Sample 1(CameraX的常規使用)
(1)CameraX 建立UseCaseConfig; //已經提早實現好各類UseCase(preview,ImageCapture,ImageAnalysis...)對應不一樣的UseCaseConfig, 開發者重要專一本身的業務。
(2)建立對應UseCase
(3)CameraX bindToLifecycle(LifeCycleOwner, UseCases) //CameraX 會觀察生命週期以肯定什麼時候打開相機、什麼時候建立拍攝會話以及什麼時候中止和關閉。
(4)CameraX unbind(UseCase)
6. Code Sample 2(CameraX的特效拓展)

Part4: 開發二三事

Rotation:

Camera1 和 Camera2 上來的數據角度是不同;Camera2的某些設備,前置攝像頭的sensor orientation是不一致的。通常前置270,後置90。android

  • 相機角度獲取: Camera1:CameraInfo.orientation Camera2:CameraCharacteristics.SENSOR_ORIENTATION
  • 手機角度: 經過傳感器獲取:
(SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
  • APP角度獲取:
經過WindowManager:
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

Coordinate system:

Camera1 和 Camera2的座標系不同,因此在View座標和相機座標系轉換的時候是不同的。git

  • Camera1的座標系:
  • Camera2的座標系:

Render:

YUV數據的紋理映射:
  • glGenTextures(...);///create glTexture id
  • glBindTextures(...); //bind texture into Gl context
  • glTexParameterf(...);//filter param set when Texture Maping
  • glTexImage2D(...); // load YUV data
  • GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0) //unBinde Texture
離屏渲染:
  • glGenFramebuffers(...);
  • glBindFramebuffer(...);
  • glFramebufferTexture2D(...); //bind frame buffer with Texture
  • glDrawArrays(...); //draw texture data into frame buffer
  • glReadPixels(...); //get frame buffer data for snapshot.
  • glBindFramebuffer(...);// unbind texture
GLSL:
  • glCreateShader(...);
  • glShaderSource(...);//bind Vertex/Segment program with Vertex/Segment object
  • glCompileShader(...);
  • glCreateProgram(...);
  • glAttachShader(...);///attach Vertex/Segment object with Shader program
  • glLinkProgram(...);
  • glUseProgram(...); //draw
總結:
Camera的數據輸出格式:
對於Texture的數據採集,直接在GPU中建立Texture Object並拿到Texture id,Camera 的採集數據直接交給texture object 進行離屏渲染。
對於Byte Buffer的數據採集,須要將YUV數據加載到紋理object,再進行離屏渲染。
兩種比較起來,直接用Texture 數據進行採集,能夠省去cpu往GPU的數據拷貝過程,更高效。

Part5:Camera Next Plane

添加本身的CameraX功能
Reference :
相關文章
相關標籤/搜索