1# Photo Capture Sample (C/C++) 2 3Before developing a camera application, request permissions by following the instructions provided in [Camera Development Preparations](camera-preparation.md). 4 5This topic provides sample code that covers the complete photo capture process and the API calling sequence. For details about a single process (such as device input, session management, and photo capture), see the corresponding C/C++ development guide links provided in [Camera Development Preparations](camera-preparation.md). 6 7## Development Process 8 9After obtaining the output stream capabilities supported by the camera, create a photo stream. The development process is as follows: 10 11 12 13## Sample Code 14 151. Link the dynamic library in the CMake script. 16 ```txt 17 target_link_libraries(entry PUBLIC 18 libace_napi.z.so 19 libhilog_ndk.z.so 20 libnative_buffer.so 21 libohcamera.so 22 libohimage.so 23 libohfileuri.so 24 ) 25 ``` 262. Create the header file **ndk_camera.h**. 27 ```c++ 28 #include "ohcamera/camera.h" 29 #include "ohcamera/camera_input.h" 30 #include "ohcamera/capture_session.h" 31 #include "ohcamera/photo_output.h" 32 #include "ohcamera/preview_output.h" 33 #include "ohcamera/video_output.h" 34 #include "ohcamera/camera_manager.h" 35 36 class NDKCamera { 37 public: 38 ~NDKCamera(); 39 NDKCamera(char *previewId); 40 Camera_ErrorCode RegisterBufferCb(void *cb); 41 }; 42 ``` 43 443. Import the NDK APIs on the C++ side, and perform photo capture based on the surface ID passed in. 45 ```c++ 46 #include "hilog/log.h" 47 #include "ndk_camera.h" 48 49 void CaptureSessionOnFocusStateChange(Camera_CaptureSession* session, Camera_FocusState focusState) 50 { 51 OH_LOG_INFO(LOG_APP, "CaptureSessionOnFocusStateChange"); 52 } 53 54 void CaptureSessionOnError(Camera_CaptureSession* session, Camera_ErrorCode errorCode) 55 { 56 OH_LOG_INFO(LOG_APP, "CaptureSessionOnError = %{public}d", errorCode); 57 } 58 59 CaptureSession_Callbacks* GetCaptureSessionRegister(void) 60 { 61 static CaptureSession_Callbacks captureSessionCallbacks = { 62 .onFocusStateChange = CaptureSessionOnFocusStateChange, 63 .onError = CaptureSessionOnError 64 }; 65 return &captureSessionCallbacks; 66 } 67 68 void PreviewOutputOnFrameStart(Camera_PreviewOutput* previewOutput) 69 { 70 OH_LOG_INFO(LOG_APP, "PreviewOutputOnFrameStart"); 71 } 72 73 void PreviewOutputOnFrameEnd(Camera_PreviewOutput* previewOutput, int32_t frameCount) 74 { 75 OH_LOG_INFO(LOG_APP, "PreviewOutputOnFrameEnd = %{public}d", frameCount); 76 } 77 78 void PreviewOutputOnError(Camera_PreviewOutput* previewOutput, Camera_ErrorCode errorCode) 79 { 80 OH_LOG_INFO(LOG_APP, "PreviewOutputOnError = %{public}d", errorCode); 81 } 82 83 PreviewOutput_Callbacks* GetPreviewOutputListener(void) 84 { 85 static PreviewOutput_Callbacks previewOutputListener = { 86 .onFrameStart = PreviewOutputOnFrameStart, 87 .onFrameEnd = PreviewOutputOnFrameEnd, 88 .onError = PreviewOutputOnError 89 }; 90 return &previewOutputListener; 91 } 92 93 void OnCameraInputError(const Camera_Input* cameraInput, Camera_ErrorCode errorCode) 94 { 95 OH_LOG_INFO(LOG_APP, "OnCameraInput errorCode = %{public}d", errorCode); 96 } 97 98 CameraInput_Callbacks* GetCameraInputListener(void) 99 { 100 static CameraInput_Callbacks cameraInputCallbacks = { 101 .onError = OnCameraInputError 102 }; 103 return &cameraInputCallbacks; 104 } 105 106 void CameraManagerStatusCallback(Camera_Manager* cameraManager, Camera_StatusInfo* status) 107 { 108 OH_LOG_INFO(LOG_APP, "CameraManagerStatusCallback is called"); 109 } 110 111 CameraManager_Callbacks* GetCameraManagerListener() 112 { 113 static CameraManager_Callbacks cameraManagerListener = { 114 .onCameraStatus = CameraManagerStatusCallback 115 }; 116 return &cameraManagerListener; 117 } 118 119 static void *bufferCb = nullptr; 120 Camera_ErrorCode NDKCamera::RegisterBufferCb(void *cb) { 121 OH_LOG_INFO(LOG_APP, " RegisterBufferCb start"); 122 if (cb == nullptr) { 123 OH_LOG_INFO(LOG_APP, " RegisterBufferCb invalid error"); 124 return CAMERA_INVALID_ARGUMENT; 125 } 126 bufferCb = cb; 127 128 return CAMERA_OK; 129 } 130 void OnPhotoAvailable(Camera_PhotoOutput *photoOutput, OH_PhotoNative *photo) { 131 OH_LOG_INFO(LOG_APP, "OnPhotoAvailable start!"); 132 OH_ImageNative *imageNative; 133 Camera_ErrorCode errCode = OH_PhotoNative_GetMainImage(photo, &imageNative); 134 OH_LOG_INFO(LOG_APP, "OnPhotoAvailable errCode:%{public}d imageNative:%{public}p", errCode, imageNative); 135 // Read the size attribute of OH_ImageNative. 136 Image_Size size; 137 Image_ErrorCode imageErr = OH_ImageNative_GetImageSize(imageNative, &size); 138 OH_LOG_INFO(LOG_APP, "OnPhotoAvailable imageErr:%{public}d width:%{public}d height:%{public}d", imageErr, 139 size.width, size.height); 140 // Read the number of elements in the component list of OH_ImageNative. 141 size_t componentTypeSize = 0; 142 imageErr = OH_ImageNative_GetComponentTypes(imageNative, nullptr, &componentTypeSize); 143 OH_LOG_INFO(LOG_APP, "OnPhotoAvailable imageErr:%{public}d componentTypeSize:%{public}zu", imageErr, 144 componentTypeSize); 145 // Read the component list of OH_ImageNative. 146 uint32_t *components = new uint32_t[componentTypeSize]; 147 imageErr = OH_ImageNative_GetComponentTypes(imageNative, &components, &componentTypeSize); 148 OH_LOG_INFO(LOG_APP, "OnPhotoAvailable OH_ImageNative_GetComponentTypes imageErr:%{public}d", imageErr); 149 // Read the buffer object corresponding to the first component of OH_ImageNative. 150 OH_NativeBuffer *nativeBuffer = nullptr; 151 imageErr = OH_ImageNative_GetByteBuffer(imageNative, components[0], &nativeBuffer); 152 OH_LOG_INFO(LOG_APP, "OnPhotoAvailable OH_ImageNative_GetByteBuffer imageErr:%{public}d", imageErr); 153 // Read the size of the buffer corresponding to the first component of OH_ImageNative. 154 size_t nativeBufferSize = 0; 155 imageErr = OH_ImageNative_GetBufferSize(imageNative, components[0], &nativeBufferSize); 156 OH_LOG_INFO(LOG_APP, "OnPhotoAvailable imageErr:%{public}d nativeBufferSize:%{public}zu", imageErr, 157 nativeBufferSize); 158 // Read the row stride corresponding to the first component of OH_ImageNative. 159 int32_t rowStride = 0; 160 imageErr = OH_ImageNative_GetRowStride(imageNative, components[0], &rowStride); 161 OH_LOG_INFO(LOG_APP, "OnPhotoAvailable imageErr:%{public}d rowStride:%{public}d", imageErr, rowStride); 162 // Read the pixel stride corresponding to the first component of OH_ImageNative. 163 int32_t pixelStride = 0; 164 imageErr = OH_ImageNative_GetPixelStride(imageNative, components[0], &pixelStride); 165 OH_LOG_INFO(LOG_APP, "OnPhotoAvailable imageErr:%{public}d pixelStride:%{public}d", imageErr, pixelStride); 166 // Map the ION memory to the process address space. 167 void *virAddr = nullptr; // Point to the virtual address of the mapped memory. After unmapping, the pointer is invalid. 168 int32_t ret = OH_NativeBuffer_Map(nativeBuffer, &virAddr); // After mapping, the start address of the memory is returned through the parameter virAddr. 169 OH_LOG_INFO(LOG_APP, "OnPhotoAvailable OH_NativeBuffer_Map err:%{public}d", ret); 170 // Pass the processed buffer to the ArkTS side through the callback for image display or storage (using a security component). For details, see Photo Capture (C/C++). 171 auto cb = (void (*)(void *, size_t))(bufferCb); 172 cb(virAddr, nativeBufferSize); 173 // After the processing is complete, unmap and release the buffer. 174 ret = OH_NativeBuffer_Unmap(nativeBuffer); 175 if (ret != 0) { 176 OH_LOG_ERROR(LOG_APP, "OnPhotoAvailable OH_NativeBuffer_Unmap error:%{public}d", ret); 177 } 178 } 179 180 NDKCamera::NDKCamera(char *previewId) 181 { 182 Camera_Manager* cameraManager = nullptr; 183 Camera_Device* cameras = nullptr; 184 Camera_CaptureSession* captureSession = nullptr; 185 Camera_OutputCapability* cameraOutputCapability = nullptr; 186 const Camera_Profile* previewProfile = nullptr; 187 const Camera_Profile* photoProfile = nullptr; 188 Camera_PreviewOutput* previewOutput = nullptr; 189 Camera_PhotoOutput* photoOutput = nullptr; 190 Camera_Input* cameraInput = nullptr; 191 uint32_t size = 0; 192 uint32_t cameraDeviceIndex = 0; 193 char* previewSurfaceId = previewId; 194 // Create a CameraManager object. 195 Camera_ErrorCode ret = OH_Camera_GetCameraManager(&cameraManager); 196 if (cameraManager == nullptr || ret != CAMERA_OK) { 197 OH_LOG_ERROR(LOG_APP, "OH_Camera_GetCameraMananger failed."); 198 } 199 // Listen for camera status changes. 200 ret = OH_CameraManager_RegisterCallback(cameraManager, GetCameraManagerListener()); 201 if (ret != CAMERA_OK) { 202 OH_LOG_ERROR(LOG_APP, "OH_CameraManager_RegisterCallback failed."); 203 } 204 205 // Obtain the camera list. 206 ret = OH_CameraManager_GetSupportedCameras(cameraManager, &cameras, &size); 207 if (cameras == nullptr || size < 0 || ret != CAMERA_OK) { 208 OH_LOG_ERROR(LOG_APP, "OH_CameraManager_GetSupportedCameras failed."); 209 } 210 211 // Create a camera input stream. 212 ret = OH_CameraManager_CreateCameraInput(cameraManager, &cameras[cameraDeviceIndex], &cameraInput); 213 if (cameraInput == nullptr || ret != CAMERA_OK) { 214 OH_LOG_ERROR(LOG_APP, "OH_CameraManager_CreateCameraInput failed."); 215 } 216 217 // Listen for camera input errors. 218 ret = OH_CameraInput_RegisterCallback(cameraInput, GetCameraInputListener()); 219 if (ret != CAMERA_OK) { 220 OH_LOG_ERROR(LOG_APP, "OH_CameraInput_RegisterCallback failed."); 221 } 222 223 // Open the camera. 224 ret = OH_CameraInput_Open(cameraInput); 225 if (ret != CAMERA_OK) { 226 OH_LOG_ERROR(LOG_APP, "OH_CameraInput_Open failed."); 227 } 228 229 // Obtain the output stream capability supported by the camera. 230 ret = OH_CameraManager_GetSupportedCameraOutputCapability(cameraManager, &cameras[cameraDeviceIndex], 231 &cameraOutputCapability); 232 if (cameraOutputCapability == nullptr || ret != CAMERA_OK) { 233 OH_LOG_ERROR(LOG_APP, "OH_CameraManager_GetSupportedCameraOutputCapability failed."); 234 } 235 236 if (cameraOutputCapability->previewProfilesSize < 0) { 237 OH_LOG_ERROR(LOG_APP, "previewProfilesSize == null"); 238 } 239 previewProfile = cameraOutputCapability->previewProfiles[0]; 240 241 if (cameraOutputCapability->photoProfilesSize < 0) { 242 OH_LOG_ERROR(LOG_APP, "photoProfilesSize == null"); 243 } 244 photoProfile = cameraOutputCapability->photoProfiles[0]; 245 246 247 // Create a preview output stream, with the previewSurfaceId parameter set to the ID of the surface provided by the XComponent. 248 ret = OH_CameraManager_CreatePreviewOutput(cameraManager, previewProfile, previewSurfaceId, &previewOutput); 249 if (previewProfile == nullptr || previewOutput == nullptr || ret != CAMERA_OK) { 250 OH_LOG_ERROR(LOG_APP, "OH_CameraManager_CreatePreviewOutput failed."); 251 } 252 253 // Listen for preview output errors. 254 ret = OH_PreviewOutput_RegisterCallback(previewOutput, GetPreviewOutputListener()); 255 if (ret != CAMERA_OK) { 256 OH_LOG_ERROR(LOG_APP, "OH_PreviewOutput_RegisterCallback failed."); 257 } 258 259 // Create a photo output stream. 260 ret = OH_CameraManager_CreatePhotoOutputWithoutSurface(cameraManager, photoProfile, &photoOutput); 261 262 // Listen for the one-time photo capture callback. 263 ret = OH_PhotoOutput_RegisterPhotoAvailableCallback(photoOutput, OnPhotoAvailable); 264 265 // Create a session. 266 ret = OH_CameraManager_CreateCaptureSession(cameraManager, &captureSession); 267 if (captureSession == nullptr || ret != CAMERA_OK) { 268 OH_LOG_ERROR(LOG_APP, "OH_CameraManager_CreateCaptureSession failed."); 269 } 270 271 // Listen for session errors. 272 ret = OH_CaptureSession_RegisterCallback(captureSession, GetCaptureSessionRegister()); 273 if (ret != CAMERA_OK) { 274 OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_RegisterCallback failed."); 275 } 276 277 // Start configuration for the session. 278 ret = OH_CaptureSession_BeginConfig(captureSession); 279 if (ret != CAMERA_OK) { 280 OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_BeginConfig failed."); 281 } 282 283 // Add the camera input stream to the session. 284 ret = OH_CaptureSession_AddInput(captureSession, cameraInput); 285 if (ret != CAMERA_OK) { 286 OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_AddInput failed."); 287 } 288 289 // Add the preview output stream to the session. 290 ret = OH_CaptureSession_AddPreviewOutput(captureSession, previewOutput); 291 if (ret != CAMERA_OK) { 292 OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_AddPreviewOutput failed."); 293 } 294 295 // Add the photo output stream to the session. 296 ret = OH_CaptureSession_AddPhotoOutput(captureSession, photoOutput); 297 if (ret != CAMERA_OK) { 298 OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_AddPhotoOutput failed."); 299 } 300 301 // Commit the session configuration. 302 ret = OH_CaptureSession_CommitConfig(captureSession); 303 if (ret != CAMERA_OK) { 304 OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_CommitConfig failed."); 305 } 306 307 // Start the session. 308 ret = OH_CaptureSession_Start(captureSession); 309 if (ret != CAMERA_OK) { 310 OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_Start failed."); 311 } 312 313 // Check whether the camera has flash. 314 Camera_FlashMode flashMode = FLASH_MODE_AUTO; 315 bool hasFlash = false; 316 ret = OH_CaptureSession_HasFlash(captureSession, &hasFlash); 317 if (ret != CAMERA_OK) { 318 OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_HasFlash failed."); 319 } 320 if (hasFlash) { 321 OH_LOG_INFO(LOG_APP, "hasFlash success"); 322 } else { 323 OH_LOG_ERROR(LOG_APP, "hasFlash fail"); 324 } 325 326 // Check whether a flash mode is supported. 327 bool isSupported = false; 328 ret = OH_CaptureSession_IsFlashModeSupported(captureSession, flashMode, &isSupported); 329 if (ret != CAMERA_OK) { 330 OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_IsFlashModeSupported failed."); 331 } 332 if (isSupported) { 333 OH_LOG_INFO(LOG_APP, "isFlashModeSupported success"); 334 335 // Set the flash mode. 336 ret = OH_CaptureSession_SetFlashMode(captureSession, flashMode); 337 if (ret == CAMERA_OK) { 338 OH_LOG_INFO(LOG_APP, "OH_CaptureSession_SetFlashMode success."); 339 } else { 340 OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_SetFlashMode failed. %{public}d ", ret); 341 } 342 343 // Obtain the flash mode in use. 344 ret = OH_CaptureSession_GetFlashMode(captureSession, &flashMode); 345 if (ret == CAMERA_OK) { 346 OH_LOG_INFO(LOG_APP, "OH_CaptureSession_GetFlashMode success. flashMode: %{public}d ", flashMode); 347 } else { 348 OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_GetFlashMode failed. %d ", ret); 349 } 350 } else { 351 OH_LOG_ERROR(LOG_APP, "isFlashModeSupported fail"); 352 } 353 354 // Check whether the continuous auto focus is supported. 355 Camera_FocusMode focusMode = FOCUS_MODE_CONTINUOUS_AUTO; 356 bool isFocusModeSupported = false; 357 ret = OH_CaptureSession_IsFocusModeSupported(captureSession, focusMode, &isFocusModeSupported); 358 if (ret != CAMERA_OK) { 359 OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_IsFocusModeSupported failed."); 360 } 361 if (isFocusModeSupported) { 362 OH_LOG_INFO(LOG_APP, "isFocusModeSupported success"); 363 ret = OH_CaptureSession_SetFocusMode(captureSession, focusMode); 364 if (ret != CAMERA_OK) { 365 OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_SetFocusMode failed. %{public}d ", ret); 366 } 367 ret = OH_CaptureSession_GetFocusMode(captureSession, &focusMode); 368 if (ret == CAMERA_OK) { 369 OH_LOG_INFO(LOG_APP, "OH_CaptureSession_GetFocusMode success. focusMode%{public}d ", focusMode); 370 } else { 371 OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_GetFocusMode failed. %d ", ret); 372 } 373 } else { 374 OH_LOG_ERROR(LOG_APP, "isFocusModeSupported fail"); 375 } 376 377 // Obtain the zoom ratio range supported by the camera. 378 float minZoom; 379 float maxZoom; 380 ret = OH_CaptureSession_GetZoomRatioRange(captureSession, &minZoom, &maxZoom); 381 if (ret != CAMERA_OK) { 382 OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_GetZoomRatioRange failed."); 383 } else { 384 OH_LOG_INFO(LOG_APP, "OH_CaptureSession_GetZoomRatioRange success. minZoom: %{public}f, maxZoom:%{public}f", 385 minZoom, maxZoom); 386 } 387 388 // Set a zoom ratio. 389 ret = OH_CaptureSession_SetZoomRatio(captureSession, maxZoom); 390 if (ret == CAMERA_OK) { 391 OH_LOG_INFO(LOG_APP, "OH_CaptureSession_SetZoomRatio success."); 392 } else { 393 OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_SetZoomRatio failed. %{public}d ", ret); 394 } 395 396 // Obtain the zoom ratio of the camera. 397 ret = OH_CaptureSession_GetZoomRatio(captureSession, &maxZoom); 398 if (ret == CAMERA_OK) { 399 OH_LOG_INFO(LOG_APP, "OH_CaptureSession_GetZoomRatio success. zoom: %{public}f ", maxZoom); 400 } else { 401 OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_GetZoomRatio failed. %{public}d ", ret); 402 } 403 404 // Take photos without photo capture settings. 405 ret = OH_PhotoOutput_Capture(photoOutput); 406 if (ret == CAMERA_OK) { 407 OH_LOG_INFO(LOG_APP, "OH_PhotoOutput_Capture success "); 408 } else { 409 OH_LOG_ERROR(LOG_APP, "OH_PhotoOutput_Capture failed. %d ", ret); 410 } 411 412 // Stop the session. 413 ret = OH_CaptureSession_Stop(captureSession); 414 if (ret == CAMERA_OK) { 415 OH_LOG_INFO(LOG_APP, "OH_CaptureSession_Stop success "); 416 } else { 417 OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_Stop failed. %d ", ret); 418 } 419 420 // Release the camera input stream. 421 ret = OH_CameraInput_Close(cameraInput); 422 if (ret == CAMERA_OK) { 423 OH_LOG_INFO(LOG_APP, "OH_CameraInput_Close success "); 424 } else { 425 OH_LOG_ERROR(LOG_APP, "OH_CameraInput_Close failed. %d ", ret); 426 } 427 428 // Release the preview output stream. 429 ret = OH_PreviewOutput_Release(previewOutput); 430 if (ret == CAMERA_OK) { 431 OH_LOG_INFO(LOG_APP, "OH_PreviewOutput_Release success "); 432 } else { 433 OH_LOG_ERROR(LOG_APP, "OH_PreviewOutput_Release failed. %d ", ret); 434 } 435 436 // Release the photo output stream. 437 ret = OH_PhotoOutput_Release(photoOutput); 438 if (ret == CAMERA_OK) { 439 OH_LOG_INFO(LOG_APP, "OH_PhotoOutput_Release success "); 440 } else { 441 OH_LOG_ERROR(LOG_APP, "OH_PhotoOutput_Release failed. %d ", ret); 442 } 443 444 // Release the session. 445 ret = OH_CaptureSession_Release(captureSession); 446 if (ret == CAMERA_OK) { 447 OH_LOG_INFO(LOG_APP, "OH_CaptureSession_Release success "); 448 } else { 449 OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_Release failed. %d ", ret); 450 } 451 452 // Release the resources. 453 ret = OH_CameraManager_DeleteSupportedCameras(cameraManager, cameras, size); 454 if (ret != CAMERA_OK) { 455 OH_LOG_ERROR(LOG_APP, "Delete Cameras failed."); 456 } else { 457 OH_LOG_ERROR(LOG_APP, "OH_CameraManager_DeleteSupportedCameras. ok"); 458 } 459 ret = OH_CameraManager_DeleteSupportedCameraOutputCapability(cameraManager, cameraOutputCapability); 460 if (ret != CAMERA_OK) { 461 OH_LOG_ERROR(LOG_APP, "Delete Cameras failed."); 462 } else { 463 OH_LOG_ERROR(LOG_APP, "OH_CameraManager_DeleteSupportedCameraOutputCapability. ok"); 464 } 465 ret = OH_Camera_DeleteCameraManager(cameraManager); 466 if (ret != CAMERA_OK) { 467 OH_LOG_ERROR(LOG_APP, "Delete Cameras failed."); 468 } else { 469 OH_LOG_ERROR(LOG_APP, "OH_Camera_DeleteCameraManager. ok"); 470 } 471 } 472 ``` 473