CameraX 1.1 有哪些新的特性發(fā)布望拖?

CameraX 是一個 Jetpack 支持庫滑绒,旨在幫助您簡化相機應(yīng)用的開發(fā)工作。它提供一致且易用的 API 接口秒梅,適用于大多數(shù) Android 設(shè)備匹表,并可向后兼容至 Android 5.0 (API 級別 21)门坷。我們將在本文中介紹 CameraX 1.1 的多項功能,比如視頻功能袍镀。

如果您更喜歡通過視頻了解此內(nèi)容默蚌,請 點擊此處 查看。

CameraX 概覽

CameraX 是一個為了簡化編寫相機應(yīng)用而設(shè)計的支持庫苇羡,它所提供的高級 API 可以讓開發(fā)者專注于和用戶交互而非相機的內(nèi)部實現(xiàn)绸吸。我們一直在探索并修復(fù)其背后復(fù)雜的兼容性問題,讓每個新版本都得以在更多的設(shè)備上穩(wěn)定運行设江。

何時使用 CameraX 或 Camera2锦茁,這取決于您期望更快的開發(fā)速度或是想要更高的自定義程度。

  • CameraX 可以很方便地實現(xiàn)普通照片視頻的拍攝功能叉存,而 Camera2 則可以對拍攝流程進行特殊控制码俩,例如實現(xiàn)多重曝光或全手動捕獲;
  • CameraX 旨在消除不同設(shè)備間的差異并在不同設(shè)備上進行了測試歼捏,而 Camera2 則需要應(yīng)用來管理不同設(shè)備間的差異并測試其行為稿存;
  • CameraX 提升了代碼開發(fā)速度,讓您更專注于用戶界面和體驗流程瞳秽,而 Camera2 則用于更深入地開發(fā)以創(chuàng)造基于相機的定制功能瓣履;
  • CameraX 發(fā)布新版本頻繁,而 Camera2 則隨著 Android 的版本而更新练俐;
  • CameraX 可以在您不熟悉相機的情況下也能夠進行開發(fā)袖迎,而 Camera2 則需要您對相機的專業(yè)知識有更深層次的了解。

CameraX 基于主要的使用場景來構(gòu)建腺晾,比如實時預(yù)覽相機燕锥、檢索緩沖區(qū)以進行分析和拍攝照片,在 CameraX 1.1 版本中還加入了視頻拍攝功能悯蝉。我們來看一個簡單的 CameraX 示例:

fun bindPreview(cameraProvider : ProcessCameraProvider) {
    // 使用 CameraX 創(chuàng)建 Preview 用例
    var preview : Preview = Preview.Builder().build()

    // 創(chuàng)建 cameraSelector归形,它會在設(shè)備上搜索所需的相機
    var cameraSelector : CameraSelector = CameraSelector.Builder()
        // 在本例中,我們選擇搜索后置相機
        .requireLensFacing(CameraSelector.LENS_FACING_BACK).build()

    // 從 CameraX 的 CameraView 包中獲取 previewView 的句柄
    // 利用此方法可以輕松的將相機內(nèi)容添加到視圖上
    preview.setSurfaceProvider(previewView.getSurfaceProvider())

    // 將 preview 與其生命周期綁定
    var camera = cameraProvider.bindToLifecycle(this as LifecycleOwner,
                                cameraSelector, preview)
}

△ CameraX 代碼示例

CameraX 是生命周期感知型組件泉粉,這意味著它將自動處理應(yīng)用的生命周期事件來實現(xiàn)開始连霉、停止、暫停和恢復(fù)∥嗣遥現(xiàn)在跺撼,應(yīng)用啟動時屏幕上便會顯示實時預(yù)覽。

我們已于 2021 年 5 月發(fā)布了 1.0 穩(wěn)定版本讨彼,目前正在開發(fā) 1.1 Alpha 版本并且很快將會進入 Beta 階段歉井。并且我們一如既往地不斷為新增設(shè)備推出兼容性修復(fù)程序,例如 1.0.1 和 1.0.2哈误。

在 CameraX 1.1 版本中我們新增了開發(fā)者呼聲很高的功能哩至,具體而言,在本文中我們將重點介紹:

  • 視頻拍攝
  • YUV 到 RGB 的轉(zhuǎn)換
  • Beta 版 Extensions API
  • 一些需要了解的其它功能

視頻拍攝

在 CameraX 1.1 版本中我們加入了視頻拍攝功能蜜自,視頻拍攝 API (尚處于 Alpha 階段菩貌,細節(jié)可能會發(fā)生變化,但整體結(jié)構(gòu)基本會保持不變) 提供了錄制到文件等基本功能重荠、可自動適配每臺設(shè)備的 Quality Setting API箭阶,以及 Lifecycle Management API。接下來我們先來了解如何設(shè)定視頻拍攝功能戈鲁,代碼示例如下:

// 創(chuàng)建 Recorder
val recorder = Recorder.Builder()
                       // 我們可以在此處使用 setQualitySelector 設(shè)置視頻質(zhì)量
                       .setQualitySelector(...)
                       .build()

// 使用新創(chuàng)建的 Recorder 創(chuàng)建 VideoCapture
val videoCapture = VideoCapture.withOutput(recorder)

// 將其與生命周期綁定
cameraProvider.bindToLifecycle(
    this, CameraSelector.DEFAULT_BACK_CAMERA, preview, videoCapture)

// 設(shè)定 VideoRecordEvent 監(jiān)聽器
val videoRecordEventListener = Consumer<VideoRecordEvent>{
    when (it) {
        is VideoRecordEvent.Start -> {}
        is VideoRecordEvent.Finalize -> {}
        is VideoRecordEvent.Status -> {
            // status 事件將會在錄制時持續(xù)更新
            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()

// 準(zhǔn)備錄制
val activeRecording = videoCapture.output.prepareRecording(this, mediaStoreOutput)
    // 關(guān)聯(lián)事件監(jiān)聽器
    .withEventListener(ContextCompat.getMainExecutor(this), videoRecordEventListener)
    // 啟用音頻 (前提是此應(yīng)用已獲得音頻權(quán)限)
    .withAudioEnabled()
    // 開始錄制
    .start()

△ 視頻拍攝示例

videoCapture 會在應(yīng)用啟動時就緒仇参,應(yīng)用可以使用 videoRecordEventListener 響應(yīng)開始、結(jié)束婆殿、暫停和恢復(fù)等拍攝事件诈乒,其中 Status 事件會提供包括文件大小和持續(xù)時間的 RecordingStats。視頻拍攝可以輸出到 File婆芦、FileDescriptorMediaStore怕磨,在本例中我們選擇 MediaStore。如果選擇啟用音頻寞缝,則需要此應(yīng)用已經(jīng)獲得音頻權(quán)限癌压。調(diào)用 start() 開始錄制為我們提供了 activeRecording 句柄,它可以用來暫停荆陆、恢復(fù)或停止錄制滩届。您可以在 1.1 版本中試用這些 API。

YUV 至 RGB 的轉(zhuǎn)換

另一個呼聲很高的功能是 YUV 到 RGB 的轉(zhuǎn)換被啼,我們來了解一下此功能帜消。

△ YUV 格式 (圖左) 轉(zhuǎn)換至 RGB 格式 (圖右)

相機通常以 YUV420 格式生成數(shù)據(jù),其中包括明亮度 (Luminance, Y)浓体、色度 (Chroma, U, V) 和一些填充字節(jié)以將各行與有效的內(nèi)存步幅對齊泡挺。但是這種格式的圖像處理起來可能很麻煩,而現(xiàn)在 CameraX 可以將 ImageAnalysis 的輸出轉(zhuǎn)換為大家更熟悉的 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 輸出

在示例代碼中娄猫,我們創(chuàng)建了 ImageAnalysis 實例贱除,為圖像緩沖區(qū)指定了所需的分辨率和背壓策略,并調(diào)用新的 setOutputImageFormat 方法以請求 RGBA 8888 格式的輸出∠蹦纾現(xiàn)在月幌,ImageAnalysis輸出的幀為 RGBA 8888 數(shù)據(jù)而不再是 YUV 格式。

CameraX 中 YUV 到 RGB 的轉(zhuǎn)換基于 libyuv悬蔽。此外铺敌,在 CameraX 1.1 版本中數(shù)據(jù)本身可以轉(zhuǎn)換到目標(biāo)分辨率泪酱。在中端設(shè)備上對圖像大小為 640x480 至 1080p 的數(shù)據(jù)進行轉(zhuǎn)換大約需要 5~10 毫秒臭胜,具體性能因設(shè)備而異庄拇。此外 APK 會略微增加 50KB 左右。

修復(fù)單像素漂移

YUV 轉(zhuǎn)換還修復(fù)了部分設(shè)備上存在的單像素漂移問題禾乘。在這些設(shè)備上澎埠,YUV 輸出經(jīng)過桶形移位一個像素,導(dǎo)致最右邊的一列數(shù)據(jù)出現(xiàn)在圖像的左邊緣始藕。在已知會發(fā)生這種情況的設(shè)備上失暂,進行 YUV 到 RGB 的轉(zhuǎn)換及輸出 YUV 或 RGB 都會被修復(fù),并且 CameraX 將會持續(xù)對更多有需要的設(shè)備進行修復(fù)鳄虱。

△ 修復(fù)單像素漂移

如需了解更多弟塞,請參閱我們之前的推文《為 CameraX ImageAnalysis 進行 YUV 到 RGB 的轉(zhuǎn)換》。

CameraX Extensions API

相機特效

在 CameraX 1.1 中的 CameraX Extensions API 可以更為充分地發(fā)揮設(shè)備強大的功能拙已。

CameraX Extensions 包括一些最常見的內(nèi)置相機特效:

  • BOKEH (焦外虛化) : 在人像模式下拍攝照片時决记,讓前景人物更清晰。
  • HDR (高動態(tài)范圍) : 拍照時使用不同的自動曝光 (AE) 配置倍踪,以獲得最佳效果系宫。
  • NIGHT (夜間) : 在低照度環(huán)境下 (通常是在夜間) 捕獲最佳靜態(tài)圖像。
  • FACE RETOUCH (臉部照片修復(fù)) : 拍攝靜態(tài)圖像時建车,修飾臉部膚色扩借、輪廓等。
  • AUTO (自動) : 根據(jù)周圍的景色自動調(diào)整最終圖像缤至。

我們來看看如何使用 CameraX Extensions API:

// 獲取后置相機列表
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

// 檢查所有的后置相機中是否有支持焦外虛化
if (extensionsManager.isExtensionAvailable(
    cameraProvider,
    cameraSelector,
    ExtensionMode.BOKEH
)) {
    // 創(chuàng)建擴展 cameraSelector潮罪,我們提供了相機并指定焦外虛化模式
    // 它將開始在后臺搜索支持焦外虛化的后置相機
    val bokehCameraSelector = extensionsManager.getExtensionCameraSelector(
        cameraProvider,
        cameraSelector,
        ExtensionMode.BOKEH
    )

    // 創(chuàng)建 imageCapture 和 preview
    val imageCapture = ImageCapture.Builder().builder()
    val preview = Preview.Builder().build()

    // 使用 bokehCameraSelector 將它們綁定到生命周期
    cameraProvider.bindToLifecycle(lifecycleOwner,
        bokehCameraSelector,
        imageCapture,
        preview
    )
}

△ 以 BOKEH 效果捕捉并預(yù)覽圖像

在上面的例子中,imageCapture 輸出的圖像將會具有焦外虛化效果领斥,如果設(shè)備支持的話嫉到,preview 也將預(yù)覽焦外虛化效果。

如需詳細了解月洛,請參閱我們之前的推文《使用 CameraX Extensions API 將特效應(yīng)用到照片上》何恶。

曝光補償

CarmeraX 1.1 中還添加了曝光補償 API,此功能可以幫助用戶更好地捕捉過度曝光或者曝光不足的區(qū)域嚼黔。

如圖所示我們所處的場景窗外很明亮而室內(nèi)很昏暗细层,此時則可以調(diào)整曝光補償來更好地捕捉明亮的室外或昏暗的室內(nèi)場景惜辑。我們來看一個例子:

// 創(chuàng)建變量來跟蹤 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)) {
        // 調(diào)用 camera.cameraControl 的 setExposureCompenstation() 方法來設(shè)置曝光補償
        camera.cameraControl.setExposureCompenstation(++exposureIndex)
        // 使用 exposureCompensationStep 來實現(xiàn)從 index 到 EV 到轉(zhuǎn)換
        val ev = camera.cameraInfo.exposureState.exposureCompensationStep.toFloat() * exposureIndex
        Log.i("CameraXLog", "EV: $ev")
    }
}

△ 通過按鈕調(diào)整曝光

其中 exposureIndex 是一個與設(shè)備無關(guān)的數(shù)字,它將以硬件允許的最小步長遞增或遞減曝光值疫赎,因此可以在不同的設(shè)備上以類似的方式運作韵丑。如果您想向用戶展示 EV 值,可以獲取 exposureCompensationStep 來實現(xiàn)轉(zhuǎn)換虚缎。

如需了解 CameraX 中曝光補償 API 的應(yīng)用背景和調(diào)用方法,請參閱我們之前的推文《CameraX 曝光補償 API 入門指南》钓株。

平滑縮放

在 CameraX 1.1 中实牡,我們還增加了平滑縮放功能。有一些設(shè)備有包括廣角和長焦在內(nèi)的多個鏡頭轴合,CameraX 可以檢測這些設(shè)備是否支持 SMOOTH_ZOOM 框架创坞,在受支持的設(shè)備上使用 CameraX 的縮放控件時,會自動使用所有的相機來實現(xiàn)更大的縮放范圍受葛。如果您已經(jīng)在使用這個縮放控件题涨,那當(dāng)您使用 1.1 版本進行編譯時,您的應(yīng)用應(yīng)該就可以訪問這些設(shè)備上的所有相機总滩。

CameraX 1.1 的更多功能

接下來介紹我們在 1.1 中添加的更多功能纲堵。

CameraState API 現(xiàn)在可以提供諸如另一個應(yīng)用正在使用相機或者正處于勿擾模式等更多有關(guān)相機狀態(tài)的信息,使得應(yīng)用能夠圍繞不同的相機時間來設(shè)計更好的界面和用戶體驗流程闰渔。Image Analysis 現(xiàn)在可以提供超過 1080p 的圖像席函。Logging API 可以更詳細的調(diào)試日志并改善了錯誤報告。Coordinate Transformation API 可以將不同用例間的坐標(biāo)關(guān)聯(lián)起來冈涧,如果您在 imageAnalysis緩沖區(qū)中定位了興趣點茂附,便可以方便地在圖像捕捉的輸出或預(yù)覽中輕松找到它。您可以使用 CameraFilter API 來指定詳細的規(guī)則以選擇合適的相機督弓。如果應(yīng)用只需要前置或者后置相機营曼,可以使用 AvailableCamerasLimiter 來加快啟動時間。CameraControllerInfo 中可提供相機功能的更多詳細信息愚隧。

設(shè)備兼容性

CameraX 會持續(xù)關(guān)注設(shè)備兼容性蒂阱,以便應(yīng)用在眾多設(shè)備上都能夠良好運行。我們修復(fù)了很多諸如圖像拉伸狂塘、縮放不正確蒜危、圖像顛倒及關(guān)閉相機時意外輸出了綠色圖形等問題。每個 CameraX 的發(fā)布版本或補丁版本中都會添加此類修復(fù)睹耐,最新的穩(wěn)定版為 1.0.2辐赞。

您可以在 版本記錄 中看到每個版本中的詳細變更,還可以在 問題跟蹤器 中看已經(jīng)修復(fù)的問題硝训。

更多信息

希望對 CameraX 1.1 版本的簡要介紹對大家有所幫助响委,非常期待看到大家使用 CameraX 構(gòu)建的功能新思!

歡迎您 點擊這里 向我們提交反饋,或分享您喜歡的內(nèi)容赘风、發(fā)現(xiàn)的問題夹囚。您的反饋對我們非常重要,感謝您的支持邀窃!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末荸哟,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子瞬捕,更是在濱河造成了極大的恐慌鞍历,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肪虎,死亡現(xiàn)場離奇詭異劣砍,居然都是意外死亡,警方通過查閱死者的電腦和手機扇救,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門刑枝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人迅腔,你說我怎么就攤上這事装畅。” “怎么了沧烈?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵洁灵,是天一觀的道長。 經(jīng)常有香客問我掺出,道長徽千,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任汤锨,我火速辦了婚禮双抽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘闲礼。我一直安慰自己牍汹,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布柬泽。 她就那樣靜靜地躺著慎菲,像睡著了一般。 火紅的嫁衣襯著肌膚如雪锨并。 梳的紋絲不亂的頭發(fā)上露该,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天,我揣著相機與錄音第煮,去河邊找鬼解幼。 笑死抑党,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的撵摆。 我是一名探鬼主播底靠,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼特铝!你這毒婦竟也來了暑中?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤鲫剿,失蹤者是張志新(化名)和其女友劉穎鳄逾,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體牵素,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年澄者,在試婚紗的時候發(fā)現(xiàn)自己被綠了笆呆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡粱挡,死狀恐怖赠幕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情询筏,我是刑警寧澤榕堰,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站嫌套,受9級特大地震影響逆屡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜踱讨,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一魏蔗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧痹筛,春花似錦莺治、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至滋早,卻和暖如春榄审,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背杆麸。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工瘟判, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留怨绣,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓拷获,卻偏偏與公主長得像篮撑,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子匆瓜,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容