Intelligent Assistant
Chat with our virtual assistant to get answers promptly.
We use essential cookies for the website to function, as well as analytics cookies for analyzing and creating statistics of the website performance. To agree to the use of analytics cookies, click "Accept All". You can manage your preferences at any time by clicking "Cookie Settings" on the footer. More Information.
HarmonyOS
You can use the APIs in ImageReceiver to create a PreviewOutput instance and obtain real-time data of the preview stream for secondary processing. For example, you can add a filter algorithm to the preview stream.
Read Camera for the API reference.
Import the NDK, which provides camera-related properties and methods.
// Include the NDK header files. #include <cstdlib> #include <hilog/log.h> #include <memory> #include <new> #include <multimedia/image_framework/image/image_native.h> #include <multimedia/image_framework/image/image_receiver_native.h> #include "ohcamera/camera.h" #include "ohcamera/camera_input.h" #include "ohcamera/capture_session.h" #include "ohcamera/preview_output.h" #include "ohcamera/camera_manager.h"
Link the dynamic library in the CMake script.
target_link_libraries(entry PUBLIC
libace_napi.z.so
libhilog_ndk.z.so
libohimage.so
libimage_receiver.so
libnative_image.so
libohcamera.so
libnative_buffer.so
)Initialize an ImageReceiver instance and obtain a surface ID.
Call OH_ImageReceiverNative_Create of the image module to create an OH_ImageReceiverNative instance, and call OH_ImageReceiverNative_GetReceivingSurfaceId of the instance to obtain a surface ID.
void InitImageReceiver() {
OH_ImageReceiverOptions* options = nullptr;
// Capture exceptions and check whether the instance is null. This example shows only the API call process.
// Set image parameters.
Image_ErrorCode errCode = OH_ImageReceiverOptions_Create(&options);
if (errCode != IMAGE_SUCCESS || options == nullptr) {
OH_LOG_ERROR(LOG_APP, "OH_ImageReceiverOptions_Create call failed");
return;
}
Image_Size imgSize;
imgSize.width = 1080; // Width of the created preview stream.
imgSize.height = 1080; // Height of the created preview stream.
int32_t capacity = 8; // Maximum number of images in BufferQueue. The recommended value is 8.
errCode = OH_ImageReceiverOptions_SetSize(options, imgSize);
if (errCode != IMAGE_SUCCESS) {
OH_LOG_ERROR(LOG_APP, "OH_ImageReceiverOptions_SetSize call failed");
}
errCode = OH_ImageReceiverOptions_SetCapacity(options, capacity);
if (errCode != IMAGE_SUCCESS) {
OH_LOG_ERROR(LOG_APP, "OH_ImageReceiverOptions_SetCapacity call failed");
}
// Create an OH_ImageReceiverNative instance.
OH_ImageReceiverNative* receiver = nullptr;
errCode = OH_ImageReceiverNative_Create(options, &receiver);
if (errCode != IMAGE_SUCCESS || receiver == nullptr) {
OH_LOG_ERROR(LOG_APP, "OH_ImageReceiverNative_Create call failed");
return;
}
// Obtain the Surface ID of the OH_ImageReceiverNative instance.
uint64_t receiverSurfaceID = 0;
errCode = OH_ImageReceiverNative_GetReceivingSurfaceId(receiver, &receiverSurfaceID);
if (errCode != IMAGE_SUCCESS) {
OH_LOG_ERROR(LOG_APP, "OH_ImageReceiverNative_GetReceivingSurfaceId call failed");
} else {
OH_LOG_INFO(LOG_APP, "receiver surfaceID:%{public}lu", receiverSurfaceID);
}
}Create a preview stream based on the surface ID obtained. (Note that you must convert the surface ID type to char * before the creation of the preview stream.) For details, see step 4 in Camera Preview (C/C++).
Create a session and enable it. For details, see Camera Session Management (C/C++).
Register an ImageReceiver callback to listen for the image content reported by each frame.
OH_ImageReceiverNative* receiver; // Instance created in step 3.
// Image callback. For details, see Media/Image Kit.
static void OnCallback(OH_ImageReceiverNative* receiver) {
if (receiver == nullptr) {
OH_LOG_ERROR(LOG_APP, "receiver is nullptr.");
return;
}
OH_LOG_INFO(LOG_APP, "ImageReceiverNativeCTest buffer available.");
// Capture exceptions and check whether the instance is null. This example shows only the API call process.
OH_ImageNative* image = nullptr;
// Obtain the image from the bufferQueue.
Image_ErrorCode errCode = OH_ImageReceiverNative_ReadNextImage(receiver, &image);
if (errCode != IMAGE_SUCCESS || image == nullptr) {
OH_LOG_ERROR(LOG_APP, "OH_ImageReceiverNative_ReadNextImage call failed.");
return;
}
// Read the image width and height.
Image_Size size;
errCode = OH_ImageNative_GetImageSize(image, &size);
if (errCode != IMAGE_SUCCESS) {
OH_LOG_ERROR(LOG_APP, "OH_ImageNative_GetImageSize call failed.");
OH_ImageNative_Release(image);
return;
}
OH_LOG_INFO(LOG_APP, "OH_ImageNative_GetImageSize errCode:%{public}d width:%{public}d height:%{public}d", errCode,
size.width, size.height);
// Obtain the image's component type.
size_t typeSize = 0;
uint32_t* types = new (std::nothrow) uint32_t[typeSize];
if (!types) {
OH_LOG_ERROR(LOG_APP, "Failed to allocate memory");
OH_ImageNative_Release(image);
return;
}
errCode = OH_ImageNative_GetComponentTypes(image, &types, &typeSize);
if (errCode != IMAGE_SUCCESS || typeSize == 0) {
OH_LOG_ERROR(LOG_APP, "typeSize is 0");
OH_ImageNative_Release(image);
delete[] types;
return;
}
uint32_t component = types[0];
// Obtain the image buffer.
OH_NativeBuffer* imageBuffer = nullptr;
errCode = OH_ImageNative_GetByteBuffer(image, component, &imageBuffer);
if (errCode != IMAGE_SUCCESS) {
OH_LOG_ERROR(LOG_APP, "OH_ImageNative_GetByteBuffer call failed.");
OH_ImageNative_Release(image);
delete[] types;
return;
}
size_t bufferSize = 0;
errCode = OH_ImageNative_GetBufferSize(image, component, &bufferSize);
if (errCode != IMAGE_SUCCESS) {
OH_LOG_ERROR(LOG_APP, "OH_ImageNative_GetBufferSize call failed.");
OH_ImageNative_Release(image);
delete[] types;
return;
}
OH_LOG_INFO(LOG_APP, "ImageReceiverNativeCTest buffer component: %{public}d size:%{public}zu", component, bufferSize);
// Obtain the row stride of the image.
int32_t stride = 0;
errCode = OH_ImageNative_GetRowStride(image, component, &stride);
if (errCode != IMAGE_SUCCESS) {
OH_LOG_ERROR(LOG_APP, "OH_ImageNative_GetRowStride call failed.");
OH_ImageNative_Release(image);
delete[] types;
return;
}
OH_LOG_INFO(LOG_APP, "ImageReceiverNativeCTest buffer stride: %{public}d.", stride);
void* srcVir = nullptr;
int32_t retCode = OH_NativeBuffer_Map(imageBuffer, &srcVir);
if (retCode != 0) {
OH_LOG_ERROR(LOG_APP, "OH_NativeBuffer_Map call failed.");
OH_ImageNative_Release(image);
delete[] types;
return;
}
uint8_t* srcBuffer = static_cast<uint8_t*>(srcVir);
// Check whether the row stride is the same as the width of the preview stream. If they are different, consider the impact of the stride on buffer reading.
if (stride == size.width) {
// Process the buffer by calling the API that does not support stride.
} else {
// Process the buffer by calling the API that supports stride or remove the stride data.
// The following uses the operation of removing the stride data as an example. Specifically, remove the stride data from the byteBuffer and obtain a new dstBuffer by means of copy.
size_t dstBufferSize = size.width * size.height * 1.5; // Camera preview stream in NV21 format.
std::unique_ptr<uint8_t[]> dstBuffer = std::make_unique<uint8_t[]>(dstBufferSize);
uint8_t* dstPtr = dstBuffer.get();
for (int j = 0; j < size.height * 1.5; j++) {
memcpy(dstPtr, srcBuffer, size.width);
dstPtr += size.width;
srcBuffer += stride;
}
// Process the buffer by calling the API that does not support stride.
}
// Release resources.
retCode = OH_NativeBuffer_Unmap(imageBuffer); // Release the buffer to ensure that the bufferQueue is rotated properly.
if (retCode != 0) {
OH_LOG_ERROR(LOG_APP, "OH_NativeBuffer_Unmap call failed.");
}
errCode = OH_ImageNative_Release(image);
if (errCode != IMAGE_SUCCESS) {
OH_LOG_ERROR(LOG_APP, "OH_ImageNative_Release call failed.");
}
delete[] types;
}
void OnImageReceiver() {
// Register the callback to listen for the image content reported by each frame.
Image_ErrorCode errCode = OH_ImageReceiverNative_On(receiver, OnCallback);
}Intelligent Assistant
Chat with our virtual assistant to get answers promptly.
Quick start
Helps you find desired resources with ease.