Skip to content
crazyma edited this page Jul 6, 2016 · 3 revisions

Welcome to the Camera2Sample wiki!

這份 Wiki 會簡介 CameraUnit 的 Code

基本Object

  • TextureView: 用來顯示 Preview
  • File: 最後照片要儲存的路徑
  • HanderThread(mBackgroundThread): 額外開一個包含 Looper 的 Thread。在過程中需要同步處理的東西,以及儲存Picture的步驟,會全部丟到這裏依序執行
  • ImageSaver: Runnable 物件,實作 Image 儲存在至 File System 的程序
  • CameraDevice.StateCallback(mStateCallback): 會追蹤指定 Camera 的狀態,包含 Opened, Disconnected, Error。比較重要的是:當確認 open 之後,會呼叫 createCameraPreviewSession
  • CameraCaptureSession: A configured capture session for a CameraDevice, used for capturing images from the camera or reprocessing images captured from the camera in the same session previously. (不知道怎麼用中文解釋XD)
  • CameraCaptureSession.CaptureCallback(mCaptureCallback): CameraCaptureSession 的狀態回傳,當 Camera Preview 設定好之後,會不斷的重複抓取影像,利用這個 Callback,我們可以決定是否現在要把影像儲存起來,亦或是不處理(也就是維持在preview)。這裏會使用到另一個參數:mState 來當作判斷的基準。

    另外要注意的是,最後要讀取拍下的照片時,會有一個自訂的 Callback,而不是使用這一個 callback object

  • CaptureRequest.Builder(mPreviewRequestBuilder): 產生 CaptureRequest 的物件,所以關於 CaptureRequest 的設定都是在這裏設定
  • CaptureRequest: 最終向 Camera 要求影像的 Request 物件

基本使用程序

  1. 一開始先在 Constructor 設定好 activity & file
  2. 呼叫 CameraUtil#resumeCamera,設定 BackgroundThread 以及 Camera
  3. 就緒之後,畫面會呈現 Preview Mode
  4. 按下拍照按鈕,會呼叫 CameraUtil#lockFocus,抓到目前影像之後,會利用 BackgroundThread 儲存圖片,並且呼叫 CameraUtil#unlockFocus,讓畫面回到 Preview Mode
  5. 如果要離開(onPause),呼叫 CameraUtil#pauseCamera

Method 作用解釋

以下會依據上述的程序,依序簡介呼叫的method的功用,至於細部的 coding ,可以自行在研究

resumeCamera

啟用BackgroundThread。判斷 TextureView 可否使用,如果可,就呼叫 openCamera ,反之會設定 SurfaceTextureListener ,就由 Listener 的回傳,我們可以調整參數(configureTransform),或是呼叫 openCamera

configureTransform

依據 Device 大小以及水平狀態,調整 TextureView 的呈現方式

openCamera

做基本的 Camera 以及 TextureView 設定。會依序呼叫:

  • setupCameraoutputs: 啟動指定Camera,並且做一些顯示的設定,包含 ImageReader 設定,手機水平設定,調整Preview Size,閃光燈的參數設定...,最後獲得CameraID
  • configureTransform: 上面有解釋
  • CameraManager.openCamera: 開啟Camera。會需要三個參數,比較重要的是 CameraDevice.StateCallback(mStateCallback),一旦正確開啟相機之後,就會呼叫 createCameraPreviewSession 了 (請參照 mStateCallback裡的設定)

createCameraPreviewSession

就是實現 Preview 效果。這裏會操作一些東西:CaptureRequest.Builder, CaptureRequest, CameraCaptureSession

簡單說,就是你要利用 CaptureRequest.Builder,建立一個 CaptureRequest,然後把 CaptureRequest 丟到 CameraCaptureSession 處理,這裏就會開始依據你的設定去操作 Camera 以及 顯示影像。

比較特別的是,他會呼叫 CameraCaptureSession#setRepeatingRequest (注意是Repeating),原因是,他會依據你針對相機的設定,持續的讀取影像,以便在畫面上呈現 Preview 畫面

lockFocus

按下拍照Button之後要呼叫的。基本做的事情有三個: 將 mPreviewRequestBuilder 做最後的設定 設定 mState ,表示我們現在要離開 Preview Mode,要進入 STATE_WAITING_LOCK 執行 mCaptureSession#capture

unlockFocus

就是把 mPreviewRequestBuilder & mCaptureSession 還原成 Preview Mode 的設定

CameraCaptureSession.CaptureCallback(mCaptureCallback)

這個callback就是camera拍照之後的回傳,這裏會分成四個階段來處理

  • STATE_PREVIEW:Preview的狀態,不用特別處理。
  • STATE_WAITING_LOCK:按下Button的狀態。如果順利抓到影像,就會呼叫 captureStillPicture。反之,會呼叫runPrecaptureSequence,進入這個狀態,就會依序跑到下面兩個state,但最終還是會呼叫 captureStillPicture
  • STATE_WAITING_PRECAPTURE
  • STATE_WAITING_NON_PRECAPTURE

captureStillPicture

最終要求讀取圖片的地方(mCaptureSession.capture)。這裏是呼叫 CameraCaptureSession#capture,表示僅僅只會抓取一次畫面。

這裏會額外定義一個 CamaraCaptureSession.CaptureCallback (不同於mCaptureCallback)。你可以在這裡自行新增抓取完之後要執行的東西。此local capturecallback 會呼叫 unlockFocus,讓 App 恢復成 Preview 狀態

Clone this wiki locally