The camera preconfiguration (preconfig) feature streamlines the development of camera applications by offering preset configurations for typical use cases and resolutions, enhancing the efficiency of the development process.
Following the general development process, it is complex to develop a camera application after obtaining a camera device. Specifically, you need to query the output configurations supported by the current camera in the specified mode, parse and filter the data in the obtained Camera_OutputCapability to find the required Camera_Profile and Camera_VideoProfile, and use the corresponding profiles to create Camera_PreviewOutput, Camera_PhotoOutput, and Camera_VideoOutput.
To streamline this process, the system provides the OH_CameraManager_CreatePreviewOutputUsedInPreconfig, OH_CameraManager_CreatePhotoOutputUsedInPreconfig, and OH_CameraManager_CreateVideoOutputUsedInPreconfig APIs for you to quickly set camera parameters in the photo capture and video recording scenarios (where Camera_SceneMode is NORMAL_PHOTO or NORMAL_VIDEO). It is recommended that you use the preconfig feature to speed up the application development cycle if you only need to customize the camera UI without the need for advanced camera application development.
The system provides four preconfiguration types (specified by Camera_PreconfigType): PRECONFIG_720P, PRECONFIG_1080P, PRECONFIG_4K, and PRECONFIG_HIGH_QUALITY. It also provides three aspect ratio specifications (specified by Camera_PreconfigRatio): 1:1 (PRECONFIG_RATIO_1_1), 4:3 (PRECONFIG_RATIO_4_3), and 16:9 (PRECONFIG_RATIO_16_9).
The capabilities supported vary according to the device. Before using preconfig, call OH_CaptureSession_CanPreconfig or OH_CaptureSession_CanPreconfigWithRatio to check whether the current camera device supports a specific combination of PreconfigType and PreconfigRatio.
The resolution specifications vary according to the aspect ratio. For details, see the following table.
Preview output in normal photo mode
| Preconfiguration Type (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 |
Photo output in normal photo mode
| Preconfiguration Type (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 | Follows the maximum capability of the sensor | Follows the maximum capability of the sensor | Follows the maximum capability of the sensor |
Preview output in normal video mode
| Preconfiguration Type (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 |
Video output in normal video mode
| Preconfiguration Type (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 |
Photo output in normal video mode
| Preconfiguration Type (PreconfigType) | PRECONFIG_RATIO_1_1 | PRECONFIG_RATIO_4_3 | PRECONFIG_RATIO_16_9 |
|---|---|---|---|
| PRECONFIG_720P | Follows the maximum capability of the sensor | Follows the maximum capability of the sensor | Follows the maximum capability of the sensor |
| PRECONFIG_1080P | Follows the maximum capability of the sensor | Follows the maximum capability of the sensor | Follows the maximum capability of the sensor |
| PRECONFIG_4K | Follows the maximum capability of the sensor | Follows the maximum capability of the sensor | Follows the maximum capability of the sensor |
| PRECONFIG_HIGH_QUALITY | Follows the maximum capability of the sensor | Follows the maximum capability of the sensor | Follows the maximum capability of the sensor |
Link the dynamic library in the CMake script.
target_link_libraries(entry PUBLIC libohcamera.so libhilog_ndk.z.so)
Import the NDK APIs on the C++ side, and perform photo capture based on the surface ID passed in.
#include "hilog/log.h"
#include "ohcamera/camera.h"
#include "ohcamera/camera_input.h"
#include "ohcamera/capture_session.h"
#include "ohcamera/photo_output.h"
#include "ohcamera/preview_output.h"
#include "ohcamera/video_output.h"
#include "ohcamera/camera_manager.h"
class NDKCamera {
public:
NDKCamera(char *previewId, char *photoId);
};
void CaptureSessionOnFocusStateChange(Camera_CaptureSession *session, Camera_FocusState focusState) {
OH_LOG_INFO(LOG_APP, "CaptureSessionOnFocusStateChange");
}
void CaptureSessionOnError(Camera_CaptureSession *session, Camera_ErrorCode errorCode) {
OH_LOG_INFO(LOG_APP, "CaptureSessionOnError = %{public}d", errorCode);
}
CaptureSession_Callbacks *GetCaptureSessionRegister(void) {
static CaptureSession_Callbacks captureSessionCallbacks = {.onFocusStateChange = CaptureSessionOnFocusStateChange,
.onError = CaptureSessionOnError};
return &captureSessionCallbacks;
}
void PreviewOutputOnFrameStart(Camera_PreviewOutput *previewOutput) {
OH_LOG_INFO(LOG_APP, "PreviewOutputOnFrameStart");
}
void PreviewOutputOnFrameEnd(Camera_PreviewOutput *previewOutput, int32_t frameCount) {
OH_LOG_INFO(LOG_APP, "PreviewOutputOnFrameEnd = %{public}d", frameCount);
}
void PreviewOutputOnError(Camera_PreviewOutput *previewOutput, Camera_ErrorCode errorCode) {
OH_LOG_INFO(LOG_APP, "PreviewOutputOnError = %{public}d", errorCode);
}
PreviewOutput_Callbacks *GetPreviewOutputListener(void) {
static PreviewOutput_Callbacks previewOutputListener = {.onFrameStart = PreviewOutputOnFrameStart,
.onFrameEnd = PreviewOutputOnFrameEnd,
.onError = PreviewOutputOnError};
return &previewOutputListener;
}
void OnCameraInputError(const Camera_Input *cameraInput, Camera_ErrorCode errorCode) {
OH_LOG_INFO(LOG_APP, "OnCameraInput errorCode = %{public}d", errorCode);
}
CameraInput_Callbacks *GetCameraInputListener(void) {
static CameraInput_Callbacks cameraInputCallbacks = {.onError = OnCameraInputError};
return &cameraInputCallbacks;
}
void CameraManagerStatusCallback(Camera_Manager *cameraManager, Camera_StatusInfo *status) {
OH_LOG_INFO(LOG_APP, "CameraManagerStatusCallback is called");
}
CameraManager_Callbacks *GetCameraManagerListener() {
static CameraManager_Callbacks cameraManagerListener = {.onCameraStatus = CameraManagerStatusCallback};
return &cameraManagerListener;
}
NDKCamera::NDKCamera(char *previewId, char *photoId) {
Camera_Manager *cameraManager = nullptr;
Camera_Device *cameras = nullptr;
Camera_CaptureSession *captureSession = nullptr;
Camera_PreviewOutput *previewOutput = nullptr;
Camera_PhotoOutput *photoOutput = nullptr;
Camera_Input *cameraInput = nullptr;
uint32_t size = 0;
uint32_t cameraDeviceIndex = 0;
char *previewSurfaceId = previewId;
char *photoSurfaceId = photoId;
// Create a CameraManager object.
Camera_ErrorCode ret = OH_Camera_GetCameraManager(&cameraManager);
if (cameraManager == nullptr || ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_Camera_GetCameraMananger failed.");
}
// Listen for camera status changes.
ret = OH_CameraManager_RegisterCallback(cameraManager, GetCameraManagerListener());
if (ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_CameraManager_RegisterCallback failed.");
}
// Obtain the camera list.
ret = OH_CameraManager_GetSupportedCameras(cameraManager, &cameras, &size);
if (cameras == nullptr || size < 0 || ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_CameraManager_GetSupportedCameras failed.");
}
// Create a camera input stream.
ret = OH_CameraManager_CreateCameraInput(cameraManager, &cameras[cameraDeviceIndex], &cameraInput);
if (cameraInput == nullptr || ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_CameraManager_CreateCameraInput failed.");
}
// Listen for camera input errors.
ret = OH_CameraInput_RegisterCallback(cameraInput, GetCameraInputListener());
if (ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_CameraInput_RegisterCallback failed.");
}
// Open the camera.
ret = OH_CameraInput_Open(cameraInput);
if (ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_CameraInput_Open failed.");
}
// Create a session.
ret = OH_CameraManager_CreateCaptureSession(cameraManager, &captureSession);
if (captureSession == nullptr || ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_CameraManager_CreateCaptureSession failed.");
}
// Listen for session errors.
ret = OH_CaptureSession_RegisterCallback(captureSession, GetCaptureSessionRegister());
if (ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_RegisterCallback failed.");
}
// Query the preconfig capability.
bool canPreconfigResult = false;
ret = OH_CaptureSession_CanPreconfig(captureSession, PRECONFIG_1080P, &canPreconfigResult);
if (ret != CAMERA_OK || !canPreconfigResult) {
OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_CanPreconfig failed.");
}
// Configure the preconfig feature.
ret = OH_CaptureSession_Preconfig(captureSession, PRECONFIG_1080P);
if (ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_Preconfig failed.");
}
// Create a preview output stream, with the previewSurfaceId parameter set to the ID of the surface provided by the XComponent.
ret = OH_CameraManager_CreatePreviewOutputUsedInPreconfig(cameraManager, previewSurfaceId, &previewOutput);
if (previewOutput == nullptr || ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_CameraManager_CreatePreviewOutput failed.");
}
// Listen for preview output errors.
ret = OH_PreviewOutput_RegisterCallback(previewOutput, GetPreviewOutputListener());
if (ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_PreviewOutput_RegisterCallback failed.");
}
// Create a photo output stream, with the photoSurfaceId parameter set to the ID of the surface obtained through ImageReceiver.
ret = OH_CameraManager_CreatePhotoOutputUsedInPreconfig(cameraManager, photoSurfaceId, &photoOutput);
if (photoOutput == nullptr || ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_CameraManager_CreatePhotoOutput failed.");
}
// Start configuration for the session.
ret = OH_CaptureSession_BeginConfig(captureSession);
if (ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_BeginConfig failed.");
}
// Add the camera input stream to the session.
ret = OH_CaptureSession_AddInput(captureSession, cameraInput);
if (ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_AddInput failed.");
}
// Add the preview output stream to the session.
ret = OH_CaptureSession_AddPreviewOutput(captureSession, previewOutput);
if (ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_AddPreviewOutput failed.");
}
// Add the photo output stream to the session.
ret = OH_CaptureSession_AddPhotoOutput(captureSession, photoOutput);
if (ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_AddPhotoOutput failed.");
}
// Commit the session configuration.
ret = OH_CaptureSession_CommitConfig(captureSession);
if (ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_CommitConfig failed.");
}
// Start the session.
ret = OH_CaptureSession_Start(captureSession);
if (ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_Start failed.");
}
// Check whether the camera has flash.
Camera_FlashMode flashMode = FLASH_MODE_AUTO;
bool hasFlash = false;
ret = OH_CaptureSession_HasFlash(captureSession, &hasFlash);
if (ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_HasFlash failed.");
}
if (hasFlash) {
OH_LOG_INFO(LOG_APP, "hasFlash success");
} else {
OH_LOG_ERROR(LOG_APP, "hasFlash fail");
}
// Check whether a flash mode is supported.
bool isSupported = false;
ret = OH_CaptureSession_IsFlashModeSupported(captureSession, flashMode, &isSupported);
if (ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_IsFlashModeSupported failed.");
}
if (isSupported) {
OH_LOG_INFO(LOG_APP, "isFlashModeSupported success");
// Set the flash mode.
ret = OH_CaptureSession_SetFlashMode(captureSession, flashMode);
if (ret == CAMERA_OK) {
OH_LOG_INFO(LOG_APP, "OH_CaptureSession_SetFlashMode success.");
} else {
OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_SetFlashMode failed. %{public}d ", ret);
}
// Obtain the flash mode in use.
ret = OH_CaptureSession_GetFlashMode(captureSession, &flashMode);
if (ret == CAMERA_OK) {
OH_LOG_INFO(LOG_APP, "OH_CaptureSession_GetFlashMode success. flashMode: %{public}d ", flashMode);
} else {
OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_GetFlashMode failed. %d ", ret);
}
} else {
OH_LOG_ERROR(LOG_APP, "isFlashModeSupported fail");
}
// Check whether the continuous auto focus is supported.
Camera_FocusMode focusMode = FOCUS_MODE_CONTINUOUS_AUTO;
bool isFocusModeSupported = false;
ret = OH_CaptureSession_IsFocusModeSupported(captureSession, focusMode, &isFocusModeSupported);
if (ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_IsFocusModeSupported failed.");
}
if (isFocusModeSupported) {
OH_LOG_INFO(LOG_APP, "isFocusModeSupported success");
ret = OH_CaptureSession_SetFocusMode(captureSession, focusMode);
if (ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_SetFocusMode failed. %{public}d ", ret);
}
ret = OH_CaptureSession_GetFocusMode(captureSession, &focusMode);
if (ret == CAMERA_OK) {
OH_LOG_INFO(LOG_APP, "OH_CaptureSession_GetFocusMode success. focusMode%{public}d ", focusMode);
} else {
OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_GetFocusMode failed. %d ", ret);
}
} else {
OH_LOG_ERROR(LOG_APP, "isFocusModeSupported fail");
}
// Obtain the zoom ratio range supported by the camera.
float minZoom;
float maxZoom;
ret = OH_CaptureSession_GetZoomRatioRange(captureSession, &minZoom, &maxZoom);
if (ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_GetZoomRatioRange failed.");
} else {
OH_LOG_INFO(LOG_APP, "OH_CaptureSession_GetZoomRatioRange success. minZoom: %{public}f, maxZoom:%{public}f",
minZoom, maxZoom);
}
// Set a zoom ratio.
ret = OH_CaptureSession_SetZoomRatio(captureSession, maxZoom);
if (ret == CAMERA_OK) {
OH_LOG_INFO(LOG_APP, "OH_CaptureSession_SetZoomRatio success.");
} else {
OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_SetZoomRatio failed. %{public}d ", ret);
}
// Obtain the zoom ratio of the camera.
ret = OH_CaptureSession_GetZoomRatio(captureSession, &maxZoom);
if (ret == CAMERA_OK) {
OH_LOG_INFO(LOG_APP, "OH_CaptureSession_GetZoomRatio success. zoom: %{public}f ", maxZoom);
} else {
OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_GetZoomRatio failed. %{public}d ", ret);
}
// Take photos without photo capture settings.
ret = OH_PhotoOutput_Capture(photoOutput);
if (ret == CAMERA_OK) {
OH_LOG_INFO(LOG_APP, "OH_PhotoOutput_Capture success ");
} else {
OH_LOG_ERROR(LOG_APP, "OH_PhotoOutput_Capture failed. %d ", ret);
}
// Stop the session.
ret = OH_CaptureSession_Stop(captureSession);
if (ret == CAMERA_OK) {
OH_LOG_INFO(LOG_APP, "OH_CaptureSession_Stop success ");
} else {
OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_Stop failed. %d ", ret);
}
// Release the camera input stream.
ret = OH_CameraInput_Close(cameraInput);
if (ret == CAMERA_OK) {
OH_LOG_INFO(LOG_APP, "OH_CameraInput_Close success ");
} else {
OH_LOG_ERROR(LOG_APP, "OH_CameraInput_Close failed. %d ", ret);
}
// Release the preview output stream.
ret = OH_PreviewOutput_Release(previewOutput);
if (ret == CAMERA_OK) {
OH_LOG_INFO(LOG_APP, "OH_PreviewOutput_Release success ");
} else {
OH_LOG_ERROR(LOG_APP, "OH_PreviewOutput_Release failed. %d ", ret);
}
// Release the photo output stream.
ret = OH_PhotoOutput_Release(photoOutput);
if (ret == CAMERA_OK) {
OH_LOG_INFO(LOG_APP, "OH_PhotoOutput_Release success ");
} else {
OH_LOG_ERROR(LOG_APP, "OH_PhotoOutput_Release failed. %d ", ret);
}
// Release the session.
ret = OH_CaptureSession_Release(captureSession);
if (ret == CAMERA_OK) {
OH_LOG_INFO(LOG_APP, "OH_CaptureSession_Release success ");
} else {
OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_Release failed. %d ", ret);
}
// Release the resources.
ret = OH_CameraManager_DeleteSupportedCameras(cameraManager, cameras, size);
if (ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "Delete Cameras failed.");
} else {
OH_LOG_ERROR(LOG_APP, "OH_CameraManager_DeleteSupportedCameras. ok");
}
ret = OH_Camera_DeleteCameraManager(cameraManager);
if (ret != CAMERA_OK) {
OH_LOG_ERROR(LOG_APP, "Delete Cameras failed.");
} else {
OH_LOG_ERROR(LOG_APP, "OH_Camera_DeleteCameraManager. ok");
}
}