Android camera2實現拍照 錄製的視頻 各種動效 支持人臉識別

1.出現的問題和解決辦法
有些手機第一次不能預覽,先用camera1打開
2.閃光燈不能很好控制都辦法
幾個影響閃光燈都因素
3.預覽都順序
4.無法打開攝像頭都原因

 


Camera2  人臉識別

1.識別的監聽
2.是否支持人臉識別
3.初始化的參數
 
 
 
不錯的demo,沒有人臉識別
 

 

需要使用的API介紹

因爲Camera2提供的功能更加強大,所以使用比Camera1會複雜許多.需要調用的API和回調也更多.這裏簡單介紹一下這些API的對應功能.好初步認識Camera2.

CameraManager

攝像頭管理類:

  主要有4個功能:

  1. 獲取攝像頭的ID
  2. 獲取攝像頭的特徵信息(比如攝像頭前後位置信息和支持的分辨率信息等等)
  3. 打開指定id的攝像頭
  4. 打開和關閉閃光燈

CameraDevice

攝像頭設備類:

  主要功能有3個

  1. 創建獲取數據請求類CaptureRequest.Builder(或者叫捕獲請求),下面會介紹這個類
  2. 創建獲取數據會話(創建預覽或者拍照的會話通道)
  3. 關閉攝像頭

CameraDevice.StateCallback

攝像頭狀態接口回調類:

  主要是負責回調攝像頭的開啓/斷開/異常/銷燬.我們使用CameraManager打開指定id的攝像頭時需要添加這個回調.

CameraCaptureSession.StateCallback

獲取數據會話的狀態接口回調類:

  我們創建相機預覽圖像/拍照/錄像都需要這個回調類,來告訴我們獲取數據會話的通道狀態是配置成功或者配置失敗.它還負責給我們回調一個重要的CameraCaptureSession提供給我們操作,這個CameraCaptureSession類我下面會介紹

CameraCaptureSession.CaptureCallback

獲取數據會話的數據接口回調類:

  負責回調獲取數據的生命週期(比如開始/進行中/完成/失敗等等),如果你並不需要對生命週期裏做操作,所以有時候沒有啥作用.但是它也是必需創建的一個回調接口類,是在創建預覽圖像/拍照/錄像的時候添加進去,但是拍照或者錄像的數據都不在這個回調接口裏出來(一開始很容易誤解,以爲拍照數據會從這裏返回).除了回調獲取數據的生命週期,還可以在回調方法裏獲取拍照或者錄製過程的的一些參數信息,比如圖片的Size/分辨率等等.

CaptureRequest.Builder

獲取數據請求配置類:

  很重要,也是我們頻繁操作的一個配置類.由CameraDevice類創建.主要負責

  1. 設置返回數據的surface(顯示預覽View比如TextureView的surface 或者 照片ImageReader的surface)
  2. 配置預覽/拍照/錄製的拍照參數,比如自動對焦/自動曝光/拍照自動閃光/設置HZ值/顏色校正等等你能在系統相機上看到的功能.

數據配置完成後交給CameraCaptureSession會話類,讓CameraCaptureSession操作提供我們需要的數據,例如圖像預覽或者拍照/錄製視頻

CameraCaptureSession

獲取數據會話類:

  很重要,是我們頻繁操作的一個數據會話類,比如創建預覽/停止預覽/拍照/錄像都要它來操作,它由CameraCaptureSession.StateCallback這個接口回調方法裏回調提供給我們.

ImageReader

圖片讀取類:

  不屬於Camera2Api的類,但是是拍照功能重要的類,照片的數據流由它緩存,然後我們提取保存到本地成爲圖片文件或者顯示在ImageView裏

 
 
問題
1.有些手機閃,有些不會
因爲設置了自動模式,可以修改,不影響照片
2.照片比較暗的情況
設置相機設備自動曝光關閉,要麼白,要麼黑
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);//
3.預覽更新和不更新也會影響黑色和白色
 
 
 
機型分析
1.三星,如果閃燈會黑
2.vivo,閃光燈有時候閃,有時候不閃
3.拍出來的照片有些曝光過度。-------要設置參數調整照片。處理照片
 
 
原理
1.預覽更新閃光燈,然後拍照。效果最好
2.拍照前更是閃光燈,不是白就是暗(系統相機採用的方案)
3.預覽不開閃光燈,拍照閃光燈,太白了
4.不加閃光燈的效果---------
 
1.預覽(有些手機無法預覽)
mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE,
        CameraMetadata.FLASH_MODE_SINGLE);
閃光燈控制的地方:
1。開啓閃光燈,mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE,
        CameraMetadata.FLASH_MODE_SINGLE);
 
1.是否會覆蓋,2者的區別
requestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
        CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);//自動閃光燈

 
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);//
 
情況測試:
1.註釋後,效果一樣
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);//
有預覽,但是黑
不註釋:有些沒有預覽,會白
2.先更新預覽,後面調用拍照,會白了
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON);
如何開啓閃光燈:
先開啓,打開閃光燈,所以的都會執行,系統的也是一樣,會有2次
 
CONTROL_AE_MODE_ON_ALWAYS_FLASH 同上,只是相機設備還控制閃光燈,拍照時總是閃光
int CONTROL_AE_MODE_ON_AUTO_FLASH 同上,只是相機設備控制閃光燈在低光條件下開啓
 
閃光燈的工作原理
 
 
1.一直開着閃光燈,但是拍出的效果不一樣
mCaptureRequestBuilder.set(CaptureRequest.FLASH_MODE,
            CaptureRequest.FLASH_MODE_TORCH);
 

爲了解釋上面的示意圖,假設我們想要同時拍攝兩張不同尺寸的圖片,並且在拍攝的過程中閃光燈必須亮起來。整個拍攝流程如下:

  1. 創建一個用於從 Pipeline 獲取圖片的 CaptureRequest。
  2. 修改 CaptureRequest 的閃光燈配置,讓閃光燈在拍照過程中亮起來。
  3. 創建兩個不同尺寸的 Surface 用於接收圖片數據,並且將它們添加到 CaptureRequest 中。
  4. 發送配置好的 CaptureRequest 到 Pipeline 中等待它返回拍照結果。
 

Capture

Capture 從執行方式上又被細分爲【單次模式】、【多次模式】和【重複模式】三種,我們來一一解釋下:

  • 單次模式(One-shot):指的是隻執行一次的 Capture 操作,例如設置閃光燈模式、對焦模式和拍一張照片等。多個一次性模式的 Capture 會進入隊列按順序執行。
  • 多次模式(Burst):指的是連續多次執行指定的 Capture 操作,該模式和多次執行單次模式的最大區別是連續多次 Capture 期間不允許插入其他任何 Capture 操作,例如連續拍攝 100 張照片,在拍攝這 100 張照片期間任何新的 Capture 請求都會排隊等待,直到拍完 100 張照片。多組多次模式的 Capture 會進入隊列按順序執行。
  • 重複模式(Repeating):指的是不斷重複執行指定的 Capture 操作,當有其他模式的 Capture 提交時會暫停該模式,轉而執行其他被模式的 Capture,當其他模式的 Capture 執行完畢後又會自動恢復繼續執行該模式的 Capture,例如顯示預覽畫面就是不斷 Capture 獲取每一幀畫面。該模式的 Capture 是全局唯一的,也就是新提交的重複模式 Capture 會覆蓋舊的重複模式 Capture。

相機的所有操作和參數配置最終都是服務於圖像捕獲,例如對焦是爲了讓某一個區域的圖像更加清晰,調節曝光補償是爲了調節圖像的亮度。因此,在 Camera2 裏面所有的相機操作和參數配置都被抽象成 Capture(捕獲)

9 CaptureRequest

CaptureRequest 是向 CameraCaptureSession 提交 Capture 請求時的信息載體,其內部包括了本次 Capture 的參數配置和接收圖像數據的 Surface。CaptureRequest 可以配置的信息非常多,包括圖像格式、圖像分辨率、傳感器控制、閃光燈控制、3A 控制等等,可以說絕大部分的相機參數都是通過 CaptureRequest 配置的。值得注意的是每一個 CaptureRequest 表示一幀畫面的操作,這意味着你可以精確控制每一幀的 Capture 操作。


 
控制曝光時間
在暗環境下拍照的時候,如果能夠適當延長曝光時間,就可以讓圖像畫面的亮度得到提高。在 Camera2 上,你可以在規定的曝光時長範圍內配置拍照的曝光時間,從而實現拍攝長曝光圖片,你甚至可以延長每一幀預覽畫面的曝光時間讓整個預覽畫面在暗環境下也能保證一定的亮度。而在 Camera1 上你只能 YY 一下。

解決方案:
1.官方demo---看下效果
1.預覽
2.生成的照片在哪
3.圖片處理
4.改變這個值怎麼會影響預覽,預覽的照片是好得。
 
 
不管我怎麼設置,自定義camera或者是使用camera2預覽的效果跟系統相機比起來就是差很多,這是爲啥啊,拍出來的照片也是,系統的最高甚至10m,而我機子的camera拍出來的才10幾kb。這是camera的拍照的方法
關於Camera2的各種操作還有許多學習的地方,包括美顏,磨皮各種模式的實現
 
 
官方demo非常不錯
 
-------------------------------------------
 
 
 

使用android.hardware.camera2打造新的自定義相機

如果不行,要進行圖片處理--openGl
視頻處理一塊
 
創建一個新的相機預覽的參數設置
 
AE和AF模式
1.\曝光增益
2.曝光時間
曝光時間主要是指底片的感光時間,曝光時間越長底片上生成的相片越亮,相反越暗。在外界光線比較暗的情況下一般要求延長曝光時間(比如說夜景)。
3.iso
感光度ISO大致分爲:25、50、100、200、400、800、1600、3200、6400、12800。數值越小,感光度越低;數值越大,感光度越高。
//獲取ISO範圍
Range<Integer> range1 = characteristics.get(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE);
//獲取快門範圍
Range<Long> range2 = characteristics.get(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE);
//獲取幀間隔範圍
Long max3 = characteristics.get(CameraCharacteristics.SENSOR_INFO_MAX_FRAME_DURATION);

int max1 = range1.getUpper();//華爲P9最大值爲3500
int min1 = range1.getLower();//華爲P9最小值爲100
Long max2 = range2.getUpper()/10 ;//華爲P9最大值1s
Long min2 = range2.getLower()/200 ;//華爲p9最小值100ns

int iso = ((Progress[0] * (max1 - min1)) / 100 + min1);
Long exposure = ((Progress[1] * (max2 - min2)) / 100 + min2);
Long frame = max3 / 1000;

//以下分別爲ISO,快門,幀間隔
           mPreviewBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, iso);
           mPreviewBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, exposure);
           mPreviewBuilder.set(CaptureRequest.SENSOR_FRAME_DURATION, frame);
參數調節:
//設置自動曝光幀率範圍previewBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,getRange());
https://blog.csdn.net/limingbocsdn/article/details/89176907

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章