Android?Camera?API作用及使用指南
一 StreamConfigurationMap
1. StreamConfigurationMap 的作用
StreamConfigurationMap 是 Android Camera2 API 中的一個(gè)核心類(lèi),用于描述相機(jī)設(shè)備支持的輸出流配置,包含以下信息:
- 支持的格式與分辨率:例如 YUV_420_888、JPEG、RAW 等格式及其對(duì)應(yīng)的分辨率列表。
- 輸入/輸出流組合規(guī)則:例如哪些格式可以同時(shí)用于 預(yù)覽、拍照 或 錄像。
- 硬件能力限制:例如是否支持 硬件級(jí)圖像處理(如 YUV 重處理)、動(dòng)態(tài)范圍模式(HDR)等。
- 幀率與時(shí)長(zhǎng)限制:如某些分辨率下支持的最小/最大幀率,或視頻錄制的最大時(shí)長(zhǎng)。
應(yīng)用通過(guò) CameraCharacteristics 獲取 StreamConfigurationMap,并基于此配置合理的 CaptureSession(例如選擇預(yù)覽和拍照的兼容分辨率)。
2. 與 cameraprovider 交互關(guān)系
(1) 數(shù)據(jù)來(lái)源
- CameraProvider 提供原始數(shù)據(jù):
Camera HAL 實(shí)現(xiàn)(如 android.hardware.camera.provider@2.4)通過(guò) getCameraCharacteristics() 方法向框架上報(bào)硬件能力,包括支持的流配置(格式、分辨率、動(dòng)態(tài)范圍等)。
- 框架封裝為 StreamConfigurationMap:
框架層(如 CameraService)解析 HAL 返回的元數(shù)據(jù),將其轉(zhuǎn)換為應(yīng)用可直接使用的 StreamConfigurationMap。
(2) 配置流程示例
- 應(yīng)用請(qǐng)求相機(jī)能力:
- 應(yīng)用調(diào)用
CameraManager.getCameraCharacteristics(cameraId)。
- 應(yīng)用調(diào)用
- 框架查詢(xún) HAL:
CameraService通過(guò)CameraProvider的 HAL 接口獲取該相機(jī)的元數(shù)據(jù)。
- HAL 返回底層配置:
CameraProvider從硬件或板級(jí)配置文件(如cam_board.xml)中讀取支持的流配置,傳遞給框架。
- 構(gòu)建 StreamConfigurationMap:
- 框架將原始數(shù)據(jù)(如
SCALER_AVAILABLE_STREAM_CONFIGURATIONS)封裝為StreamConfigurationMap對(duì)象。
- 框架將原始數(shù)據(jù)(如
- 應(yīng)用使用配置:
- 應(yīng)用根據(jù)
StreamConfigurationMap選擇兼容的流組合(例如同時(shí)支持1080p@30fps預(yù)覽和12MP拍照)。
- 應(yīng)用根據(jù)
(3) 關(guān)鍵數(shù)據(jù)結(jié)構(gòu)對(duì)應(yīng)
HAL 元數(shù)據(jù)字段(如 android.scaler) | StreamConfigurationMap 方法 | 作用 |
|---|---|---|
SCALER_AVAILABLE_STREAM_CONFIGURATIONS | getOutputSizes(int format) | 獲取某格式支持的分辨率列表 |
SCALER_AVAILABLE_MIN_FRAME_DURATIONS | getOutputMinFrameDuration(int format) | 獲取某分辨率下最小幀間隔(決定最大幀率) |
REQUEST_AVAILABLE_CAPABILITIES | isOutputSupportedFor(int useCase) | 檢查是否支持特定用例(如 ZSL) |
3. 實(shí)際示例
假設(shè)一個(gè)相機(jī)設(shè)備支持以下配置(通過(guò) CameraProvider 上報(bào)):
- YUV_420_888: 1920x1080@30fps, 1280x720@60fps
- JPEG: 4000x3000@10fps
則 StreamConfigurationMap 會(huì)生成如下信息:
// 獲取 YUV 格式支持的分辨率
Size[] yuvSizes = streamConfigMap.getOutputSizes(ImageFormat.YUV_420_888);
// 結(jié)果: [1920x1080, 1280x720]
// 檢查是否支持硬件級(jí) YUV 重處理
boolean isReprocessSupported = streamConfigMap.isOutputSupportedFor(
CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING);StreamConfigurationMap 是應(yīng)用層獲取相機(jī)輸出能力的接口,而 CameraProvider 是底層硬件能力的提供者。前者依賴(lài)后者上報(bào)的元數(shù)據(jù),二者共同實(shí)現(xiàn) 硬件能力到應(yīng)用接口的透明映射,是 Android Camera 系統(tǒng)分層架構(gòu)的核心設(shè)計(jì)之一。
在 Android 相機(jī)系統(tǒng)(Camera2 API)中,OutputConfiguration 和 StreamConfigurationMap 是與相機(jī)輸出流配置相關(guān)的兩個(gè)關(guān)鍵類(lèi),它們?cè)谙鄼C(jī)工作流程中扮演不同角色。以下是它們的詳細(xì)介紹及關(guān)系分析:
二. OutputConfiguration
1 作用
作用:
OutputConfiguration 是 Android 5.0(API 21)引入的類(lèi),用于定義單個(gè)相機(jī)輸出流的配置。它的核心功能包括:
- 封裝輸出目標(biāo)(如
Surface或SurfaceView)。 - 配置物理相機(jī)(在多攝像頭設(shè)備中指定物理傳感器)。
- 管理共享輸出流(允許多個(gè)
Surface共享同一輸出流)。 - 使用場(chǎng)景:
- 當(dāng)創(chuàng)建
CameraCaptureSession時(shí),需傳入一組OutputConfiguration對(duì)象,描述所有輸出流。 - 關(guān)鍵方法:
addSurface(Surface surface):添加共享的Surface。setPhysicalCameraId(String id):指定物理相機(jī)(用于雙攝/多攝設(shè)備)。getSurfaces():獲取關(guān)聯(lián)的Surface列表。
- 示例:
// 創(chuàng)建 ImageReader 并獲取 Surface
ImageReader imageReader = ImageReader.newInstance(width, height, format, maxImages);
Surface imageSurface = imageReader.getSurface();
// 創(chuàng)建 OutputConfiguration
OutputConfiguration outputConfig = new OutputConfiguration(imageSurface);
// 可選:配置共享 Surface 或物理相機(jī)
// outputConfig.addSurface(anotherSurface);
// outputConfig.setPhysicalCameraId("2");
// 創(chuàng)建 CameraCaptureSession
List<OutputConfiguration> outputConfigs = new ArrayList<>();
outputConfigs.add(outputConfig);
cameraDevice.createCaptureSessionByOutputConfigurations(outputConfigs, callback, handler);2. 與 StreamConfigurationMap 關(guān)系
協(xié)作流程:
- Step 1:通過(guò)
StreamConfigurationMap查詢(xún)?cè)O(shè)備支持的輸出參數(shù)(格式、分辨率等)。 - Step 2:根據(jù)合法參數(shù)創(chuàng)建輸出目標(biāo)(如
ImageReader或SurfaceView)。 - Step 3:將輸出目標(biāo)封裝到
OutputConfiguration,用于創(chuàng)建CameraCaptureSession。
依賴(lài)關(guān)系:
OutputConfiguration的參數(shù)(如格式、分辨率)必須符合StreamConfigurationMap的約束,否則會(huì)話(huà)創(chuàng)建會(huì)失敗。StreamConfigurationMap提供理論支持,OutputConfiguration負(fù)責(zé)實(shí)際配置。
擴(kuò)展功能:
OutputConfiguration支持高級(jí)功能(如多攝像頭共享輸出流),而StreamConfigurationMap僅描述硬件能力。- 在 Android 10(API 29)后,
OutputConfiguration新增對(duì)動(dòng)態(tài)分辨率、物理攝像頭綁定的支持。
3. 常見(jiàn)問(wèn)題
Q1: 為什么需要同時(shí)使用兩者?
A: StreamConfigurationMap是相機(jī)設(shè)備的“能力說(shuō)明書(shū)”,告訴開(kāi)發(fā)者硬件支持哪些輸出配置。OutputConfiguration是實(shí)際構(gòu)建輸出流的“施工圖”,將合法的參數(shù)綁定到具體的Surface`。
二者配合確保相機(jī)輸出流的正確性和高效性
Q2: 如何避免 InvalidSurfaceException?
A: 確保 OutputConfiguration 的 Surface 參數(shù)(格式、分辨率)在 StreamConfigurationMap 的合法范圍內(nèi)。
Q3: 多攝像頭場(chǎng)景如何處理?
A: 使用 OutputConfiguration.setPhysicalCameraId() 指定物理攝像頭,并通過(guò) StreamConfigurationMap 檢查該攝像頭是否支持目標(biāo)參數(shù)。
總結(jié) StreamConfigurationMap 是相機(jī)設(shè)備的“能力說(shuō)明書(shū)”,告訴開(kāi)發(fā)者硬件支持哪些輸出配置。OutputConfiguration 是實(shí)際構(gòu)建輸出流的“施工圖”,將合法的參數(shù)綁定到具體的 Surface。二者配合確保相機(jī)輸出流的正確性和高效性,是 Camera2 API 中不可或缺的組件。
在 Android Camera2 API 中,CameraCaptureSession 是管理相機(jī)數(shù)據(jù)流和捕獲請(qǐng)求的核心組件。它與 OutputConfiguration 密切相關(guān),共同決定了相機(jī)的輸出目標(biāo)(如預(yù)覽、拍照、錄像等)的配置和運(yùn)行機(jī)制。以下是詳細(xì)解釋及其與 OutputConfiguration 的關(guān)系:
三 CameraCaptureSession
1. 作用
CameraCaptureSession 是相機(jī)設(shè)備(CameraDevice)與輸出目標(biāo)(Surface)之間的橋梁,負(fù)責(zé):
管理輸出流:綁定多個(gè) Surface(如預(yù)覽的 SurfaceView、拍照的 ImageReader),并確保數(shù)據(jù)正確傳輸?shù)竭@些目標(biāo)。
提交捕獲請(qǐng)求:通過(guò) capture() 或 setRepeatingRequest() 發(fā)送請(qǐng)求(CaptureRequest),控制相機(jī)的行為(如自動(dòng)對(duì)焦、曝光、幀率等)。
處理異步事件:監(jiān)聽(tīng)相機(jī)狀態(tài)(如對(duì)焦完成、幀捕獲完成)并回調(diào)給應(yīng)用。
2 生命周期
- 創(chuàng)建:通過(guò)
CameraDevice.createCaptureSession()或createCaptureSessionByOutputConfigurations()創(chuàng)建。 - 活動(dòng)狀態(tài):可提交捕獲請(qǐng)求,相機(jī)數(shù)據(jù)流向綁定的
Surface。 - 關(guān)閉:調(diào)用
close()釋放資源,不可再發(fā)送請(qǐng)求。
3.創(chuàng)建 CameraCaptureSession
創(chuàng)建會(huì)話(huà)時(shí),需要指定一組輸出目標(biāo)(Surface 或 OutputConfiguration)。兩種方法:
傳統(tǒng)方式(基于 Surface 列表):
cameraDevice.createCaptureSession(
List<Surface> outputs, // 直接傳遞 Surface 列表
CameraCaptureSession.StateCallback callback,
Handler handler
);適用于簡(jiǎn)單場(chǎng)景,但靈活性有限(例如不支持多攝像頭或動(dòng)態(tài)分辨率)。
基于 OutputConfiguration 的方式(API 21+,擴(kuò)展功能在后續(xù)版本增強(qiáng)):
cameraDevice.createCaptureSessionByOutputConfigurations(
List<OutputConfiguration> outputConfigurations, // 封裝了 Surface 的高級(jí)配置
CameraCaptureSession.StateCallback callback,
Handler handler
);支持更復(fù)雜的配置(如共享流、物理攝像頭綁定、動(dòng)態(tài)分辨率等)。
4. 與 OutputConfiguration 的關(guān)系
(1) OutputConfiguration 是會(huì)話(huà)的輸入
- 功能:
OutputConfiguration封裝了一個(gè)或多個(gè)Surface的配置信息,用于定義輸出流的特性:- 單個(gè)或共享的
Surface:通過(guò)addSurface()添加多個(gè)Surface,共享同一數(shù)據(jù)流(例如預(yù)覽和錄像共享同一幀數(shù)據(jù))。 - 物理攝像頭綁定:在雙攝/多攝設(shè)備中,通過(guò)
setPhysicalCameraId()指定輸出流來(lái)自哪個(gè)物理攝像頭。 - 動(dòng)態(tài)分辨率(API 23+):允許在會(huì)話(huà)運(yùn)行時(shí)動(dòng)態(tài)調(diào)整分辨率(需硬件支持)。
- 單個(gè)或共享的
- 優(yōu)勢(shì):相比直接傳遞
Surface列表,OutputConfiguration提供了更細(xì)粒度的控制能力。
(2) 創(chuàng)建會(huì)話(huà)的流程
- 查詢(xún)?cè)O(shè)備支持:通過(guò)
StreamConfigurationMap確認(rèn)相機(jī)支持的格式和分辨率。 - 創(chuàng)建輸出目標(biāo):根據(jù)合法參數(shù)創(chuàng)建
Surface(如ImageReader、SurfaceView)。 - 封裝為 OutputConfiguration:將
Surface及其附加配置(如物理攝像頭)封裝到OutputConfiguration。 - 創(chuàng)建會(huì)話(huà):調(diào)用
createCaptureSessionByOutputConfigurations(),傳入OutputConfiguration列表。
(3) 關(guān)鍵約束
- 不可變性:一旦
CameraCaptureSession創(chuàng)建成功,其綁定的OutputConfiguration不可修改(如新增或移除Surface)。若需更改,必須關(guān)閉當(dāng)前會(huì)話(huà)并重新創(chuàng)建。 - 硬件限制:
OutputConfiguration的配置(如分辨率、格式)必須符合StreamConfigurationMap的支持范圍。
5. 示例:使用 OutputConfiguration 創(chuàng)建會(huì)話(huà)
// 創(chuàng)建兩個(gè)輸出目標(biāo):預(yù)覽 Surface 和拍照 ImageReader
SurfaceView surfaceView = ... // 預(yù)覽的 SurfaceView
ImageReader imageReader = ImageReader.newInstance(4032, 3024, ImageFormat.JPEG, 3);
// 封裝為 OutputConfiguration
OutputConfiguration previewConfig = new OutputConfiguration(surfaceView.getHolder().getSurface());
OutputConfiguration captureConfig = new OutputConfiguration(imageReader.getSurface());
// 可選:配置共享流或物理攝像頭
// previewConfig.addSurface(anotherSurface); // 共享同一個(gè)流
// captureConfig.setPhysicalCameraId("1"); // 指定物理攝像頭
List<OutputConfiguration> outputConfigs = new ArrayList<>();
outputConfigs.add(previewConfig);
outputConfigs.add(captureConfig);
// 創(chuàng)建 CameraCaptureSession
cameraDevice.createCaptureSessionByOutputConfigurations(outputConfigs,
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
// 會(huì)話(huà)就緒,可提交 CaptureRequest
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
// 配置失敗(參數(shù)不合法或硬件問(wèn)題)
}
},
null // 可選 Handler
);6. 高級(jí)功能與兼容性
- 共享流(Shared Surfaces):
- 多個(gè)
Surface共享同一輸出流(例如預(yù)覽和 AI 分析共享數(shù)據(jù)),減少內(nèi)存和功耗。 - 實(shí)現(xiàn)方式:通過(guò)
OutputConfiguration.addSurface()添加多個(gè)Surface。
- 多個(gè)
- 動(dòng)態(tài)分辨率(Dynamic Resolution)(API 23+):
- 允許在會(huì)話(huà)運(yùn)行時(shí)動(dòng)態(tài)調(diào)整輸出分辨率(需設(shè)備支持)。
- 通過(guò)
OutputConfiguration.setDynamicRangeProfile()配置。
- 多攝像頭支持(API 28+):
- 在雙攝設(shè)備中,通過(guò)
OutputConfiguration.setPhysicalCameraId()指定輸出流來(lái)源。
- 在雙攝設(shè)備中,通過(guò)
7. 常見(jiàn)問(wèn)題與解決方案
- 問(wèn)題1:
createCaptureSession失敗,錯(cuò)誤為IllegalArgumentException。 - 原因:
OutputConfiguration參數(shù)不合法(如分辨率超出支持范圍)。 - 解決:檢查
StreamConfigurationMap的合法參數(shù)。 - 問(wèn)題2:無(wú)法在運(yùn)行時(shí)修改輸出流。
- 原因:
CameraCaptureSession的配置不可變。 - 解決:關(guān)閉當(dāng)前會(huì)話(huà),重新創(chuàng)建新的會(huì)話(huà)。
- 問(wèn)題3:多攝像頭場(chǎng)景下數(shù)據(jù)流混亂。
- 原因:未正確指定
setPhysicalCameraId()。 - 解決:確保每個(gè)
OutputConfiguration綁定到正確的物理攝像頭。
總結(jié)
CameraCaptureSession:是相機(jī)數(shù)據(jù)流的核心控制器,負(fù)責(zé)管理輸出目標(biāo)和捕獲請(qǐng)求。- 與
OutputConfiguration的關(guān)系:OutputConfiguration是會(huì)話(huà)的輸入,定義了每個(gè)輸出流的具體配置(如Surface、物理攝像頭)。CameraCaptureSession通過(guò)OutputConfiguration的配置,確保數(shù)據(jù)流符合硬件能力(由StreamConfigurationMap定義)。- 使用
OutputConfiguration可以啟用高級(jí)功能(如共享流、多攝像頭),而傳統(tǒng)Surface列表方式功能受限。
通過(guò)合理使用 OutputConfiguration,開(kāi)發(fā)者可以更靈活地配置相機(jī)輸出流,滿(mǎn)足復(fù)雜場(chǎng)景的需求(如多攝、動(dòng)態(tài)分辨率、低功耗共享流)。
到此這篇關(guān)于Android Camera API 介紹的文章就介紹到這了,更多相關(guān)Android Camera API內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺析Android Service中實(shí)現(xiàn)彈出對(duì)話(huà)框的坑
這篇文章主要介紹了Android Service中實(shí)現(xiàn)彈出對(duì)話(huà)框的坑,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
Android開(kāi)發(fā)常用標(biāo)簽小結(jié)
這篇文章主要介紹了Android開(kāi)發(fā)常用標(biāo)簽,分析總結(jié)了Android開(kāi)發(fā)中常見(jiàn)標(biāo)簽的使用技巧,需要的朋友可以參考下2015-05-05
Android studio實(shí)現(xiàn)菜單操作
這篇文章主要為大家詳細(xì)介紹了Android studio實(shí)現(xiàn)菜單操作,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
SurfaceView實(shí)現(xiàn)紅包雨平移動(dòng)畫(huà)
這篇文章主要為大家詳細(xì)介紹了SurfaceView實(shí)現(xiàn)紅包雨平移動(dòng)畫(huà),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07
Android?PickerScrollView滑動(dòng)選擇控件使用方法詳解
這篇文章主要為大家詳細(xì)介紹了Android?PickerScrollView滑動(dòng)選擇控件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04
Kotlin 協(xié)程 supervisorScope {} 運(yùn)行崩潰解決方法
看過(guò)很多?supervisorScope {}?文檔的使用,我照抄一摸一樣的代碼,運(yùn)行就崩潰,最后找到了解決方法,應(yīng)該是kotlin版本更新做過(guò)改動(dòng),當(dāng)前我使用的是?androidx.core:core-ktx:1.9.0,本文給大家介紹Kotlin 協(xié)程 supervisorScope {} 運(yùn)行崩潰解決方法,感興趣的朋友一起看看吧2024-01-01
Android webview注入JS代碼 修改網(wǎng)頁(yè)內(nèi)容操作
這篇文章主要介紹了Android webview注入JS代碼 修改網(wǎng)頁(yè)內(nèi)容操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-03-03
Android開(kāi)發(fā)之媒體播放工具類(lèi)完整示例
這篇文章主要介紹了Android開(kāi)發(fā)之媒體播放工具類(lèi),結(jié)合完整實(shí)例形式分析了基于MediaPlayer的事件監(jiān)聽(tīng)與多媒體文件播放相關(guān)操作技巧,需要的朋友可以參考下2018-02-02
Android實(shí)現(xiàn)將View保存成Bitmap的方法
這篇文章主要介紹了Android實(shí)現(xiàn)將View保存成Bitmap的方法,涉及Android畫(huà)布Canvas、位圖bitmap及View的相關(guān)使用技巧,需要的朋友可以參考下2016-06-06
Android 6.0 藍(lán)牙搜索不到設(shè)備原因,MIUI權(quán)限申請(qǐng)機(jī)制方法
今天小編就為大家分享一篇Android6.0 藍(lán)牙搜索不到設(shè)備原因,MIUI權(quán)限申請(qǐng)機(jī)制方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-07-07

