文档管理中心
我的
您当前正在浏览新版开发者文档中心,目录分类和层级有所调整。点击左侧当前文档分类名称前的“☰”图标,可切换文档分类。 了解新版目录
指南媒体Camera Kit(相机服务)开发相机应用基础能力(C/C++)使用相机预配置(C/C++)

使用相机预配置(C/C++)

相机预配置(Preconfig),对常用的场景和分辨率进行了预配置集成,可简化开发相机应用流程,提高应用的开发效率。

开发者在开发相机应用时,在获取到CameraDevice之后,如果遵循通用流程开发,步骤较为繁琐。需要先查询当前相机在指定模式下所支持的各类输出的配置信息,拿到Camera_OutputCapability之后,应用开发者还需要对里面的各类数据进行解析,筛选,找到自己需要的配置数据Camera_Profile和Camera_VideoProfile。最后使用对应的Profile以及VideoProfile创建对应的Camera_PreviewOutput、Camera_PhotoOutput以及Camera_VideoOutput。

为了解决上述问题,优化应用开发流程,系统针对拍照、录像两类场景(即Camera_SceneMode为NORMAL_PHOTO或NORMAL_VIDEO),提供了OH_CameraManager_CreatePreviewOutputUsedInPreconfig、OH_CameraManager_CreatePhotoOutputUsedInPreconfig、OH_CameraManager_CreateVideoOutputUsedInPreconfig接口帮助开发者快速完成相机参数配置。推荐仅需要自定义拍照界面的无需开发专业相机应用的开发者,使用相机预配置功能快速开发应用。

规格说明

系统提供了4种预配置类型(Camera_PreconfigType),分别为PRECONFIG_720P、PRECONFIG_1080P、PRECONFIG_4K、PRECONFIG_HIGH_QUALITY。以及3种画幅比例规格(Camera_PreconfigRatio),1:1画幅(PRECONFIG_RATIO_1_1)、4:3画幅(PRECONFIG_RATIO_4_3)、16:9画幅(PRECONFIG_RATIO_16_9)。

注意

由于不同的设备所支持的能力不同。使用相机预配置(preconfig)功能时,需要先调用OH_CaptureSession_CanPreconfig或OH_CaptureSession_CanPreconfigWithRatio检查对应的PreconfigType和PreconfigRatio的组合在当前设备上是否支持。

在不同的画幅比例下,其分辨率规格不同,详见下表。

  • 普通拍照模式下的预览输出

    展开
    预配置类型PreconfigType PRECONFIG_RATIO_1_1 PRECONFIG_RATIO_4_3 PRECONFIG_RATIO_16_9
    PRECONFIG_720P 720x720 960x720 1280x720
    PRECONFIG_1080P 1080x1080 1440x1080 1920x1080
    PRECONFIG_4K 1080x1080 1440x1080 1920x1080
    PRECONFIG_HIGH_QUALITY 1440x1440 1920x1440 2560x1440
  • 普通拍照模式下的拍照输出

    展开
    预配置类型PreconfigType PRECONFIG_RATIO_1_1 PRECONFIG_RATIO_4_3 PRECONFIG_RATIO_16_9
    PRECONFIG_720P 720x720 960x720 1280x720
    PRECONFIG_1080P 1080x1080 1440x1080 1920x1080
    PRECONFIG_4K 2160x2160 2880x2160 3840x2160
    PRECONFIG_HIGH_QUALITY 跟随Sensor最大能力 跟随Sensor最大能力 跟随Sensor最大能力
  • 普通录像模式下的预览输出

    展开
    预配置类型PreconfigType PRECONFIG_RATIO_1_1 PRECONFIG_RATIO_4_3 PRECONFIG_RATIO_16_9
    PRECONFIG_720P 720x720 960x720 1280x720
    PRECONFIG_1080P 1080x1080 1440x1080 1920x1080
    PRECONFIG_4K 1080x1080 1440x1080 1920x1080
    PRECONFIG_HIGH_QUALITY 1080x1080 1440x1080 1920x1080
  • 普通录像模式下的录像输出

    展开
    预配置类型PreconfigType PRECONFIG_RATIO_1_1 PRECONFIG_RATIO_4_3 PRECONFIG_RATIO_16_9
    PRECONFIG_720P 720x720 960x720 1280x720
    PRECONFIG_1080P 1080x1080 1440x1080 1920x1080
    PRECONFIG_4K 2160x2160 2880x2160 3840x2160
    PRECONFIG_HIGH_QUALITY 2160x2160 2880x2160 3840x2160
  • 普通录像模式下的拍照输出

    展开
    预配置类型PreconfigType PRECONFIG_RATIO_1_1 PRECONFIG_RATIO_4_3 PRECONFIG_RATIO_16_9
    PRECONFIG_720P 跟随Sensor最大能力 跟随Sensor最大能力 跟随Sensor最大能力
    PRECONFIG_1080P 跟随Sensor最大能力 跟随Sensor最大能力 跟随Sensor最大能力
    PRECONFIG_4K 跟随Sensor最大能力 跟随Sensor最大能力 跟随Sensor最大能力
    PRECONFIG_HIGH_QUALITY 跟随Sensor最大能力 跟随Sensor最大能力 跟随Sensor最大能力

开发示例

  1. 在CMake脚本中链接相关动态库。

    收起
    自动换行
    深色代码主题
    复制
    1. target_link_libraries(entry PUBLIC libohcamera.so libhilog_ndk.z.so)
  2. cpp侧导入NDK接口,并根据传入的SurfaceId进行拍照。

    收起
    自动换行
    深色代码主题
    复制
    1. #include "hilog/log.h"
    2. #include "ohcamera/camera.h"
    3. #include "ohcamera/camera_input.h"
    4. #include "ohcamera/capture_session.h"
    5. #include "ohcamera/photo_output.h"
    6. #include "ohcamera/preview_output.h"
    7. #include "ohcamera/video_output.h"
    8. #include "ohcamera/camera_manager.h"
    9. class NDKCamera {
    10. public:
    11. NDKCamera(char *previewId, char *photoId);
    12. };
    13. void CaptureSessionOnFocusStateChange(Camera_CaptureSession *session, Camera_FocusState focusState) {
    14. OH_LOG_INFO(LOG_APP, "CaptureSessionOnFocusStateChange");
    15. }
    16. void CaptureSessionOnError(Camera_CaptureSession *session, Camera_ErrorCode errorCode) {
    17. OH_LOG_INFO(LOG_APP, "CaptureSessionOnError = %{public}d", errorCode);
    18. }
    19. CaptureSession_Callbacks *GetCaptureSessionRegister(void) {
    20. static CaptureSession_Callbacks captureSessionCallbacks = {.onFocusStateChange = CaptureSessionOnFocusStateChange,
    21. .onError = CaptureSessionOnError};
    22. return &captureSessionCallbacks;
    23. }
    24. void PreviewOutputOnFrameStart(Camera_PreviewOutput *previewOutput) {
    25. OH_LOG_INFO(LOG_APP, "PreviewOutputOnFrameStart");
    26. }
    27. void PreviewOutputOnFrameEnd(Camera_PreviewOutput *previewOutput, int32_t frameCount) {
    28. OH_LOG_INFO(LOG_APP, "PreviewOutputOnFrameEnd = %{public}d", frameCount);
    29. }
    30. void PreviewOutputOnError(Camera_PreviewOutput *previewOutput, Camera_ErrorCode errorCode) {
    31. OH_LOG_INFO(LOG_APP, "PreviewOutputOnError = %{public}d", errorCode);
    32. }
    33. PreviewOutput_Callbacks *GetPreviewOutputListener(void) {
    34. static PreviewOutput_Callbacks previewOutputListener = {.onFrameStart = PreviewOutputOnFrameStart,
    35. .onFrameEnd = PreviewOutputOnFrameEnd,
    36. .onError = PreviewOutputOnError};
    37. return &previewOutputListener;
    38. }
    39. void OnCameraInputError(const Camera_Input *cameraInput, Camera_ErrorCode errorCode) {
    40. OH_LOG_INFO(LOG_APP, "OnCameraInput errorCode = %{public}d", errorCode);
    41. }
    42. CameraInput_Callbacks *GetCameraInputListener(void) {
    43. static CameraInput_Callbacks cameraInputCallbacks = {.onError = OnCameraInputError};
    44. return &cameraInputCallbacks;
    45. }
    46. void CameraManagerStatusCallback(Camera_Manager *cameraManager, Camera_StatusInfo *status) {
    47. OH_LOG_INFO(LOG_APP, "CameraManagerStatusCallback is called");
    48. }
    49. CameraManager_Callbacks *GetCameraManagerListener() {
    50. static CameraManager_Callbacks cameraManagerListener = {.onCameraStatus = CameraManagerStatusCallback};
    51. return &cameraManagerListener;
    52. }
    53. NDKCamera::NDKCamera(char *previewId, char *photoId) {
    54. Camera_Manager *cameraManager = nullptr;
    55. Camera_Device *cameras = nullptr;
    56. Camera_CaptureSession *captureSession = nullptr;
    57. Camera_PreviewOutput *previewOutput = nullptr;
    58. Camera_PhotoOutput *photoOutput = nullptr;
    59. Camera_Input *cameraInput = nullptr;
    60. uint32_t size = 0;
    61. uint32_t cameraDeviceIndex = 0;
    62. char *previewSurfaceId = previewId;
    63. char *photoSurfaceId = photoId;
    64. // 创建CameraManager对象
    65. Camera_ErrorCode ret = OH_Camera_GetCameraManager(&cameraManager);
    66. if (cameraManager == nullptr || ret != CAMERA_OK) {
    67. OH_LOG_ERROR(LOG_APP, "OH_Camera_GetCameraMananger failed.");
    68. }
    69. // 监听相机状态变化
    70. ret = OH_CameraManager_RegisterCallback(cameraManager, GetCameraManagerListener());
    71. if (ret != CAMERA_OK) {
    72. OH_LOG_ERROR(LOG_APP, "OH_CameraManager_RegisterCallback failed.");
    73. }
    74. // 获取相机列表
    75. ret = OH_CameraManager_GetSupportedCameras(cameraManager, &cameras, &size);
    76. if (cameras == nullptr || size < 0 || ret != CAMERA_OK) {
    77. OH_LOG_ERROR(LOG_APP, "OH_CameraManager_GetSupportedCameras failed.");
    78. }
    79. // 创建相机输入流
    80. ret = OH_CameraManager_CreateCameraInput(cameraManager, &cameras[cameraDeviceIndex], &cameraInput);
    81. if (cameraInput == nullptr || ret != CAMERA_OK) {
    82. OH_LOG_ERROR(LOG_APP, "OH_CameraManager_CreateCameraInput failed.");
    83. }
    84. // 监听cameraInput错误信息
    85. ret = OH_CameraInput_RegisterCallback(cameraInput, GetCameraInputListener());
    86. if (ret != CAMERA_OK) {
    87. OH_LOG_ERROR(LOG_APP, "OH_CameraInput_RegisterCallback failed.");
    88. }
    89. // 打开相机
    90. ret = OH_CameraInput_Open(cameraInput);
    91. if (ret != CAMERA_OK) {
    92. OH_LOG_ERROR(LOG_APP, "OH_CameraInput_Open failed.");
    93. }
    94. // 创建会话
    95. ret = OH_CameraManager_CreateCaptureSession(cameraManager, &captureSession);
    96. if (captureSession == nullptr || ret != CAMERA_OK) {
    97. OH_LOG_ERROR(LOG_APP, "OH_CameraManager_CreateCaptureSession failed.");
    98. }
    99. // 监听session错误信息
    100. ret = OH_CaptureSession_RegisterCallback(captureSession, GetCaptureSessionRegister());
    101. if (ret != CAMERA_OK) {
    102. OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_RegisterCallback failed.");
    103. }
    104. // 查询Preconfig能力
    105. bool canPreconfigResult = false;
    106. ret = OH_CaptureSession_CanPreconfig(captureSession, PRECONFIG_1080P, &canPreconfigResult);
    107. if (ret != CAMERA_OK || !canPreconfigResult) {
    108. OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_CanPreconfig failed.");
    109. }
    110. // 配置Preconfig
    111. ret = OH_CaptureSession_Preconfig(captureSession, PRECONFIG_1080P);
    112. if (ret != CAMERA_OK) {
    113. OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_Preconfig failed.");
    114. }
    115. // 创建预览输出流,其中参数 previewSurfaceId 参考上文 XComponent 组件,预览流为XComponent组件提供的surface
    116. ret = OH_CameraManager_CreatePreviewOutputUsedInPreconfig(cameraManager, previewSurfaceId, &previewOutput);
    117. if (previewOutput == nullptr || ret != CAMERA_OK) {
    118. OH_LOG_ERROR(LOG_APP, "OH_CameraManager_CreatePreviewOutput failed.");
    119. }
    120. // 监听预览输出错误信息
    121. ret = OH_PreviewOutput_RegisterCallback(previewOutput, GetPreviewOutputListener());
    122. if (ret != CAMERA_OK) {
    123. OH_LOG_ERROR(LOG_APP, "OH_PreviewOutput_RegisterCallback failed.");
    124. }
    125. // 创建拍照输出流,其中参数 photoSurfaceId 参考上文 ImageReceiver获取的surface
    126. ret = OH_CameraManager_CreatePhotoOutputUsedInPreconfig(cameraManager, photoSurfaceId, &photoOutput);
    127. if (photoOutput == nullptr || ret != CAMERA_OK) {
    128. OH_LOG_ERROR(LOG_APP, "OH_CameraManager_CreatePhotoOutput failed.");
    129. }
    130. // 开始配置会话
    131. ret = OH_CaptureSession_BeginConfig(captureSession);
    132. if (ret != CAMERA_OK) {
    133. OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_BeginConfig failed.");
    134. }
    135. // 向会话中添加相机输入流
    136. ret = OH_CaptureSession_AddInput(captureSession, cameraInput);
    137. if (ret != CAMERA_OK) {
    138. OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_AddInput failed.");
    139. }
    140. // 向会话中添加预览输出流
    141. ret = OH_CaptureSession_AddPreviewOutput(captureSession, previewOutput);
    142. if (ret != CAMERA_OK) {
    143. OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_AddPreviewOutput failed.");
    144. }
    145. // 向会话中添加拍照输出流
    146. ret = OH_CaptureSession_AddPhotoOutput(captureSession, photoOutput);
    147. if (ret != CAMERA_OK) {
    148. OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_AddPhotoOutput failed.");
    149. }
    150. // 提交会话配置
    151. ret = OH_CaptureSession_CommitConfig(captureSession);
    152. if (ret != CAMERA_OK) {
    153. OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_CommitConfig failed.");
    154. }
    155. // 启动会话
    156. ret = OH_CaptureSession_Start(captureSession);
    157. if (ret != CAMERA_OK) {
    158. OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_Start failed.");
    159. }
    160. // 判断设备是否支持闪光灯
    161. Camera_FlashMode flashMode = FLASH_MODE_AUTO;
    162. bool hasFlash = false;
    163. ret = OH_CaptureSession_HasFlash(captureSession, &hasFlash);
    164. if (ret != CAMERA_OK) {
    165. OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_HasFlash failed.");
    166. }
    167. if (hasFlash) {
    168. OH_LOG_INFO(LOG_APP, "hasFlash success");
    169. } else {
    170. OH_LOG_ERROR(LOG_APP, "hasFlash fail");
    171. }
    172. // 检测闪光灯模式是否支持
    173. bool isSupported = false;
    174. ret = OH_CaptureSession_IsFlashModeSupported(captureSession, flashMode, &isSupported);
    175. if (ret != CAMERA_OK) {
    176. OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_IsFlashModeSupported failed.");
    177. }
    178. if (isSupported) {
    179. OH_LOG_INFO(LOG_APP, "isFlashModeSupported success");
    180. // 设置闪光灯模式
    181. ret = OH_CaptureSession_SetFlashMode(captureSession, flashMode);
    182. if (ret == CAMERA_OK) {
    183. OH_LOG_INFO(LOG_APP, "OH_CaptureSession_SetFlashMode success.");
    184. } else {
    185. OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_SetFlashMode failed. %{public}d ", ret);
    186. }
    187. // 获取当前设备的闪光灯模式
    188. ret = OH_CaptureSession_GetFlashMode(captureSession, &flashMode);
    189. if (ret == CAMERA_OK) {
    190. OH_LOG_INFO(LOG_APP, "OH_CaptureSession_GetFlashMode success. flashMode:%{public}d ", flashMode);
    191. } else {
    192. OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_GetFlashMode failed. %d ", ret);
    193. }
    194. } else {
    195. OH_LOG_ERROR(LOG_APP, "isFlashModeSupported fail");
    196. }
    197. // 判断是否支持连续自动变焦模式
    198. Camera_FocusMode focusMode = FOCUS_MODE_CONTINUOUS_AUTO;
    199. bool isFocusModeSupported = false;
    200. ret = OH_CaptureSession_IsFocusModeSupported(captureSession, focusMode, &isFocusModeSupported);
    201. if (ret != CAMERA_OK) {
    202. OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_IsFocusModeSupported failed.");
    203. }
    204. if (isFocusModeSupported) {
    205. OH_LOG_INFO(LOG_APP, "isFocusModeSupported success");
    206. ret = OH_CaptureSession_SetFocusMode(captureSession, focusMode);
    207. if (ret != CAMERA_OK) {
    208. OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_SetFocusMode failed. %{public}d ", ret);
    209. }
    210. ret = OH_CaptureSession_GetFocusMode(captureSession, &focusMode);
    211. if (ret == CAMERA_OK) {
    212. OH_LOG_INFO(LOG_APP, "OH_CaptureSession_GetFocusMode success. focusMode%{public}d ", focusMode);
    213. } else {
    214. OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_GetFocusMode failed. %d ", ret);
    215. }
    216. } else {
    217. OH_LOG_ERROR(LOG_APP, "isFocusModeSupported fail");
    218. }
    219. // 获取相机支持的可变焦距比范围
    220. float minZoom;
    221. float maxZoom;
    222. ret = OH_CaptureSession_GetZoomRatioRange(captureSession, &minZoom, &maxZoom);
    223. if (ret != CAMERA_OK) {
    224. OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_GetZoomRatioRange failed.");
    225. } else {
    226. OH_LOG_INFO(LOG_APP, "OH_CaptureSession_GetZoomRatioRange success. minZoom: %{public}f, maxZoom:%{public}f",
    227. minZoom, maxZoom);
    228. }
    229. // 设置变焦
    230. ret = OH_CaptureSession_SetZoomRatio(captureSession, maxZoom);
    231. if (ret == CAMERA_OK) {
    232. OH_LOG_INFO(LOG_APP, "OH_CaptureSession_SetZoomRatio success.");
    233. } else {
    234. OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_SetZoomRatio failed. %{public}d ", ret);
    235. }
    236. // 获取当前设备的变焦值
    237. ret = OH_CaptureSession_GetZoomRatio(captureSession, &maxZoom);
    238. if (ret == CAMERA_OK) {
    239. OH_LOG_INFO(LOG_APP, "OH_CaptureSession_GetZoomRatio success. zoom:%{public}f ", maxZoom);
    240. } else {
    241. OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_GetZoomRatio failed. %{public}d ", ret);
    242. }
    243. // 无拍照设置进行拍照
    244. ret = OH_PhotoOutput_Capture(photoOutput);
    245. if (ret == CAMERA_OK) {
    246. OH_LOG_INFO(LOG_APP, "OH_PhotoOutput_Capture success ");
    247. } else {
    248. OH_LOG_ERROR(LOG_APP, "OH_PhotoOutput_Capture failed. %d ", ret);
    249. }
    250. // 停止当前会话
    251. ret = OH_CaptureSession_Stop(captureSession);
    252. if (ret == CAMERA_OK) {
    253. OH_LOG_INFO(LOG_APP, "OH_CaptureSession_Stop success ");
    254. } else {
    255. OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_Stop failed. %d ", ret);
    256. }
    257. // 释放相机输入流
    258. ret = OH_CameraInput_Close(cameraInput);
    259. if (ret == CAMERA_OK) {
    260. OH_LOG_INFO(LOG_APP, "OH_CameraInput_Close success ");
    261. } else {
    262. OH_LOG_ERROR(LOG_APP, "OH_CameraInput_Close failed. %d ", ret);
    263. }
    264. // 释放预览输出流
    265. ret = OH_PreviewOutput_Release(previewOutput);
    266. if (ret == CAMERA_OK) {
    267. OH_LOG_INFO(LOG_APP, "OH_PreviewOutput_Release success ");
    268. } else {
    269. OH_LOG_ERROR(LOG_APP, "OH_PreviewOutput_Release failed. %d ", ret);
    270. }
    271. // 释放拍照输出流
    272. ret = OH_PhotoOutput_Release(photoOutput);
    273. if (ret == CAMERA_OK) {
    274. OH_LOG_INFO(LOG_APP, "OH_PhotoOutput_Release success ");
    275. } else {
    276. OH_LOG_ERROR(LOG_APP, "OH_PhotoOutput_Release failed. %d ", ret);
    277. }
    278. // 释放会话
    279. ret = OH_CaptureSession_Release(captureSession);
    280. if (ret == CAMERA_OK) {
    281. OH_LOG_INFO(LOG_APP, "OH_CaptureSession_Release success ");
    282. } else {
    283. OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_Release failed. %d ", ret);
    284. }
    285. // 资源释放
    286. ret = OH_CameraManager_DeleteSupportedCameras(cameraManager, cameras, size);
    287. if (ret != CAMERA_OK) {
    288. OH_LOG_ERROR(LOG_APP, "Delete Cameras failed.");
    289. } else {
    290. OH_LOG_INFO(LOG_APP, "OH_CameraManager_DeleteSupportedCameras. ok");
    291. }
    292. ret = OH_Camera_DeleteCameraManager(cameraManager);
    293. if (ret != CAMERA_OK) {
    294. OH_LOG_ERROR(LOG_APP, "Delete Cameras failed.");
    295. } else {
    296. OH_LOG_INFO(LOG_APP, "OH_Camera_DeleteCameraManager. ok");
    297. }
    298. }