CameraX 是一個 Jetpack 支持庫,旨在幫助您簡化相機應用的開發工作。它提供一致且易用的 API 接口,適用于大多數 Android 設備,并可向后兼容至 Android 5.0 (API 級別 21)。我們將在本文中介紹 CameraX 1.1 的多項功能,比如視頻功能。
CameraX 概覽
CameraX 是一個為了簡化編寫相機應用而設計的支持庫,它所提供的高級 API 可以讓開發者專注于和用戶交互而非相機的內部實現。我們一直在探索并修復其背后復雜的兼容性問題,讓每個新版本都得以在更多的設備上穩定運行。
何時使用 CameraX 或 Camera2,這取決于您期望更快的開發速度或是想要更高的自定義程度。
CameraX 可以很方便地實現普通照片視頻的拍攝功能,而 Camera2 則可以對拍攝流程進行特殊控制,例如實現多重曝光或全手動捕獲;
CameraX 旨在消除不同設備間的差異并在不同設備上進行了測試,而 Camera2 則需要應用來管理不同設備間的差異并測試其行為;
CameraX 提升了代碼開發速度,讓您更專注于用戶界面和體驗流程,而 Camera2 則用于更深入地開發以創造基于相機的定制功能;
CameraX 發布新版本頻繁,而 Camera2 則隨著 Android 的版本而更新;
CameraX 可以在您不熟悉相機的情況下也能夠進行開發,而 Camera2 則需要您對相機的專業知識有更深層次的了解。
CameraX 基于主要的使用場景來構建,比如實時預覽相機、檢索緩沖區以進行分析和拍攝照片,在 CameraX 1.1 版本中還加入了視頻拍攝功能。我們來看一個簡單的 CameraX 示例:
fun bindPreview(cameraProvider : ProcessCameraProvider) {
// 使用 CameraX 創建 Preview 用例
var preview : Preview = Preview.Builder().build()
// 創建 cameraSelector,它會在設備上搜索所需的相機
var cameraSelector : CameraSelector = CameraSelector.Builder()
// 在本例中,我們選擇搜索后置相機
.requireLensFacing(CameraSelector.LENS_FACING_BACK).build()
// 從 CameraX 的 CameraView 包中獲取 previewView 的句柄
// 利用此方法可以輕松的將相機內容添加到視圖上
preview.setSurfaceProvider(previewView.getSurfaceProvider())
// 將 preview 與其生命周期綁定
var camera = cameraProvider.bindToLifecycle(this as LifecycleOwner,
cameraSelector, preview)
}
△ CameraX 代碼示例
CameraX 是生命周期感知型組件,這意味著它將自動處理應用的生命周期事件來實現開始、停止、暫停和恢復。現在,應用啟動時屏幕上便會顯示實時預覽。
我們已于 2021 年 5 月發布了 1.0 穩定版本,目前正在開發 1.1 Alpha 版本并且很快將會進入 Beta 階段。并且我們一如既往地不斷為新增設備推出兼容性修復程序,例如 1.0.1 和 1.0.2。
在 CameraX 1.1 版本中我們新增了開發者呼聲很高的功能,具體而言,在本文中我們將重點介紹:
視頻拍攝
YUV 到 RGB 的轉換
Beta 版 Extensions API
一些需要了解的其它功能
視頻拍攝在 CameraX 1.1 版本中我們加入了視頻拍攝功能,視頻拍攝 API (尚處于 Alpha 階段,細節可能會發生變化,但整體結構基本會保持不變) 提供了錄制到文件等基本功能、可自動適配每臺設備的 Quality Setting API,以及 Lifecycle Management API。接下來我們先來了解如何設定視頻拍攝功能,代碼示例如下:
// 創建 Recorder
val recorder = Recorder.Builder()
// 我們可以在此處使用 setQualitySelector 設置視頻質量
.setQualitySelector(...)
.build()
// 使用新創建的 Recorder 創建 VideoCapture
val videoCapture = VideoCapture.withOutput(recorder)
// 將其與生命周期綁定
cameraProvider.bindToLifecycle(
this, CameraSelector.DEFAULT_BACK_CAMERA, preview, videoCapture)
// 設定 VideoRecordEvent 監聽器
val videoRecordEventListener = Consumer{
when (it) {
is VideoRecordEvent.Start -> {}
is VideoRecordEvent.Finalize -> {}
is VideoRecordEvent.Status -> {
// status 事件將會在錄制時持續更新
val stats: RecordingStats = it.recordingStats
// RecordingStats 中包含錄制文件的尺寸和時長
}
is VideoRecordEvent.Pause -> {}
is VideoRecordEvent.Resume -> {}
// 指定輸出
val mediaStoreOutput = MediaStoreOutputOptions.Builder(this.contentResolver,
MediaStore.Video.Media.EXTERNAL_CONTENT_URI)
.setContentValues(contentValues)
.build()
// 準備錄制
val activeRecording = videoCapture.output.prepareRecording(this, mediaStoreOutput)
// 關聯事件監聽器
.withEventListener(ContextCompat.getMainExecutor(this), videoRecordEventListener)
// 啟用音頻 (前提是此應用已獲得音頻權限)
.withAudioEnabled()
// 開始錄制
.start()
△ 視頻拍攝示例
videoCapture 會在應用啟動時就緒,應用可以使用 videoRecordEventListener 響應開始、結束、暫停和恢復等拍攝事件,其中 Status 事件會提供包括文件大小和持續時間的 RecordingStats。視頻拍攝可以輸出到 File、FileDescriptor 或 MediaStore,在本例中我們選擇 MediaStore。如果選擇啟用音頻,則需要此應用已經獲得音頻權限。調用 start() 開始錄制為我們提供了 activeRecording 句柄,它可以用來暫停、恢復或停止錄制。您可以在 1.1 版本中試用這些 API。
YUV 至 RGB 的轉換
另一個呼聲很高的功能是 YUV 到 RGB 的轉換,我們來了解一下此功能。
相機通常以 YUV420 格式生成數據,其中包括明亮度 (Luminance, Y)、色度 (Chroma, U, V) 和一些填充字節以將各行與有效的內存步幅對齊。但是這種格式的圖像處理起來可能很麻煩,而現在 CameraX 可以將 ImageAnalysis 的輸出轉換為大家更熟悉的 RGBA 以方便處理。接下來我們看一個示例:
val imageAnalysis = ImageAnalysis.Builder()
.setTargetResolution(Size(1280, 720))
.setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888)
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build()
△ 從 ImageAnalysis 獲取 RGB 輸出
在示例代碼中,我們創建了 ImageAnalysis 實例,為圖像緩沖區指定了所需的分辨率和背壓策略,并調用新的 setOutputImageFormat 方法以請求 RGBA 8888 格式的輸出。現在,ImageAnalysis 輸出的幀為 RGBA 8888 數據而不再是 YUV 格式。
CameraX 中 YUV 到 RGB 的轉換基于 libyuv。此外,在 CameraX 1.1 版本中數據本身可以轉換到目標分辨率。在中端設備上對圖像大小為 640x480 至 1080p 的數據進行轉換大約需要 5~10 毫秒,具體性能因設備而異。此外 APK 會略微增加 50KB 左右。
修復單像素漂移
CameraX Extensions API
相機特效在 CameraX 1.1 中的 CameraX Extensions API 可以更為充分地發揮設備強大的功能。
CameraX Extensions 包括一些最常見的內置相機特效:
BOKEH (焦外虛化): 在人像模式下拍攝照片時,讓前景人物更清晰。
HDR (高動態范圍): 拍照時使用不同的自動曝光 (AE) 配置,以獲得最佳效果。
NIGHT (夜間): 在低照度環境下 (通常是在夜間) 捕獲最佳靜態圖像。
FACE RETOUCH (臉部照片修復): 拍攝靜態圖像時,修飾臉部膚色、輪廓等。
AUTO (自動): 根據周圍的景色自動調整最終圖像。
我們來看看如何使用 CameraX Extensions API:
△ 以 BOKEH 效果捕捉并預覽圖像// 獲取后置相機列表
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
// 檢查所有的后置相機中是否有支持焦外虛化
if (extensionsManager.isExtensionAvailable(
cameraProvider,
cameraSelector,
ExtensionMode.BOKEH
)) {
// 創建擴展 cameraSelector,我們提供了相機并指定焦外虛化模式
// 它將開始在后臺搜索支持焦外虛化的后置相機
val bokehCameraSelector = extensionsManager.getExtensionCameraSelector(
cameraProvider,
cameraSelector,
ExtensionMode.BOKEH
)
// 創建 imageCapture 和 preview
val imageCapture = ImageCapture.Builder().builder()
val preview = Preview.Builder().build()
// 使用 bokehCameraSelector 將它們綁定到生命周期
cameraProvider.bindToLifecycle(lifecycleOwner,
bokehCameraSelector,
imageCapture,
preview
)
}
在上面的例子中,imageCapture 輸出的圖像將會具有焦外虛化效果,如果設備支持的話,preview 也將預覽焦外虛化效果。
曝光補償
CameraX 1.1 中還添加了曝光補償 API,此功能可以幫助用戶更好地捕捉過度曝光或者曝光不足的區域。
如圖所示我們所處的場景窗外很明亮而室內很昏暗,此時則可以調整曝光補償來更好地捕捉明亮的室外或昏暗的室內場景。我們來看一個例子:
// 創建變量來跟蹤 exposureIndex 值
var exposureIndex = 0
// 使用 cameraSelector 將 imageCapture 和 preview 綁定到生命周期
val camera = cameraProvider.bindToLifecycle(
lifecycleOwner,
getCameraSelector(),
preview,
imageCapture
)
// 為視圖中的按鈕添加點擊事件
evButton.setOnclickListener {
// 檢查有效的范圍以防止可能的異常
val range = camera.cameraInfo.exposureState.exposureCompensationRange
if (range.contains(exposureIndex + 1)) {
// 調用 camera.cameraControl 的 setExposureCompenstation() 方法來設置曝光補償
camera.cameraControl.setExposureCompenstation(++exposureIndex)
// 使用 exposureCompensationStep 來實現從 index 到 EV 到轉換
val ev = camera.cameraInfo.exposureState.exposureCompensationStep.toFloat() * exposureIndex
Log.i("CameraXLog", "EV: $ev")
}
}
△ 通過按鈕調整曝光
其中 exposureIndex 是一個與設備無關的數字,它將以硬件允許的最小步長遞增或遞減曝光值,因此可以在不同的設備上以類似的方式運作。如果您想向用戶展示 EV 值,可以獲取 exposureCompensationStep 來實現轉換。
平滑縮放
在 CameraX 1.1 中,我們還增加了平滑縮放功能。有一些設備有包括廣角和長焦在內的多個鏡頭,CameraX 可以檢測這些設備是否支持 SMOOTH_ZOOM 框架,在受支持的設備上使用 CameraX 的縮放控件時,會自動使用所有的相機來實現更大的縮放范圍。如果您已經在使用這個縮放控件,那當您使用 1.1 版本進行編譯時,您的應用應該就可以訪問這些設備上的所有相機。
CameraX 1.1 的更多功能
接下來介紹我們在 1.1 中添加的更多功能。
CameraState API 現在可以提供諸如另一個應用正在使用相機或者正處于勿擾模式等更多有關相機狀態的信息,使得應用能夠圍繞不同的相機時間來設計更好的界面和用戶體驗流程。Image Analysis 現在可以提供超過 1080p 的圖像。Logging API 可以更詳細的調試日志并改善了錯誤報告。Coordinate Transformation API 可以將不同用例間的坐標關聯起來,如果您在 imageAnalysis 緩沖區中定位了興趣點,便可以方便地在圖像捕捉的輸出或預覽中輕松找到它。您可以使用 CameraFilter API 來指定詳細的規則以選擇合適的相機。如果應用只需要前置或者后置相機,可以使用 AvailableCamerasLimiter 來加快啟動時間。CameraControllerInfo 中可提供相機功能的更多詳細信息。
設備兼容性
CameraX 會持續關注設備兼容性,以便應用在眾多設備上都能夠良好運行。我們修復了很多諸如圖像拉伸、縮放不正確、圖像顛倒及關閉相機時意外輸出了綠色圖形等問題。每個 CameraX 的發布版本或補丁版本中都會添加此類修復,最新的穩定版為 1.0.2。
您可以在版本記錄中看到每個版本中的詳細變更,還可以在問題跟蹤器中看已經修復的問題。
希望對 CameraX 1.1 版本的簡要介紹對大家有所幫助,非常期待看到大家使用 CameraX 構建的功能!
原文標題:CameraX 1.1 有哪些新的特性發布?
文章出處:【微信公眾號:谷歌開發者】歡迎添加關注!文章轉載請注明出處。
審核編輯:湯梓紅
-
Android
+關注
關注
12文章
3923瀏覽量
127137 -
相機
+關注
關注
4文章
1344瀏覽量
53509 -
設備
+關注
關注
2文章
4473瀏覽量
70540
原文標題:CameraX 1.1 有哪些新的特性發布?
文章出處:【微信號:Google_Developers,微信公眾號:谷歌開發者】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論