1# 使用Image_NativeModule完成图片接收 2<!--Kit: Image Kit--> 3<!--Subsystem: Multimedia--> 4<!--Owner: @aulight02--> 5<!--Designer: @liyang_bryan--> 6<!--Tester: @xchaosioda--> 7<!--Adviser: @zengyawen--> 8 9图像接收类,用于获取组件surface id、接收最新的图片和读取下一张图片、释放ImageReceiver实例。结合camera API实现的相机预览示例代码可参考[C/C++预览流二次处理示例](../camera/native-camera-preview-imageReceiver.md)。 10 11> **说明:** 12> ImageReceiver只作为图片的接收方、消费者,在ImageReceiver设置的size、format等属性实际上并不会生效。图片属性需要在发送方、生产者进行设置,可参考[预览(C/C++)](../camera/native-camera-preview.md)设置previewProfiles。 13 14## 开发步骤 15 16### 添加依赖 17 18在进行应用开发之前,开发者需要打开native工程的src/main/cpp/CMakeLists.txt,在target_link_libraries依赖中添加libohimage.so、libimage_receiver.so、libnative_image.so以及日志依赖libhilog_ndk.z.so。 19 20```txt 21target_link_libraries(entry PUBLIC libhilog_ndk.z.so libohimage.so libimage_receiver.so libnative_image.so) 22``` 23 24### Native接口调用 25 26具体接口说明请参考[API文档](../../reference/apis-image-kit/capi-image-nativemodule.md)。 27 28在Deveco Studio新建Native C++应用,默认生成的项目中包含index.ets文件,在entry\src\main\cpp目录下会自动生成一个cpp文件(hello.cpp或napi_init.cpp,本示例以hello.cpp文件名为例)。在hello.cpp中实现C API接口调用逻辑,示例代码如下: 29 30```c++ 31#include <hilog/log.h> 32#include <multimedia/image_framework/image/image_native.h> 33#include <multimedia/image_framework/image/image_receiver_native.h> 34 35#undef LOG_DOMAIN 36#define LOG_DOMAIN 0x3200 37 38#undef LOG_TAG 39#define LOG_TAG "MY_TAG" 40 41#define IMAGE_WIDTH 320 42#define IMAGE_HEIGHT 480 43#define IMAGE_CAPACITY 2 44 45static OH_ImageReceiverNative* receiver = nullptr; 46static OH_ImageReceiverOptions* options = nullptr; 47 48static void OnCallback(OH_ImageReceiverNative *receiver) 49{ 50 // callback回调处理接收到的图像数据。 51 OH_LOG_INFO(LOG_APP, "ImageReceiverNativeCTest buffer available."); 52 53 // 读取 OH_ImageReceiverNative 的下一个图片对象。 54 OH_ImageNative* image = nullptr; 55 Image_ErrorCode errCode = OH_ImageReceiverNative_ReadNextImage(receiver, &image); 56 // 结合实际使用情况,此处也可以调用OH_ImageReceiverNative_ReadLatestImage方法获取图像数据。 57 if (errCode != IMAGE_SUCCESS) { 58 OH_LOG_ERROR(LOG_APP, "ImageReceiverNativeCTest get image receiver next image failed, errCode: %{public}d.", errCode); 59 OH_ImageReceiverOptions_Release(options); 60 OH_ImageReceiverNative_Release(receiver); 61 return; 62 } 63 64 // 应用自行处理image图像数据。 65 // ... 66 67 // 释放 OH_ImageNative 实例。 68 errCode = OH_ImageNative_Release(image); 69 if (errCode != IMAGE_SUCCESS) { 70 OH_LOG_ERROR(LOG_APP, "ImageReceiverNativeCTest release image native failed, errCode: %{public}d.", errCode); 71 } 72} 73 74static void ImageReceiverNativeCTest() 75{ 76 // 创建 OH_ImageReceiverOptions 实例。 77 Image_ErrorCode errCode = OH_ImageReceiverOptions_Create(&options); 78 if (errCode != IMAGE_SUCCESS) { 79 OH_LOG_ERROR(LOG_APP, "ImageReceiverNativeCTest create image receiver options failed, errCode: %{public}d.", errCode); 80 return; 81 } 82 83 Image_Size imgSize; 84 imgSize.width = IMAGE_WIDTH; 85 imgSize.height = IMAGE_HEIGHT; 86 87 // 设置 OH_ImageReceiverOptions 的 size 属性。该属性仅为必要入参,实际上不会生效,图片属性由生产者决定,如相机。 88 errCode = OH_ImageReceiverOptions_SetSize(options, imgSize); 89 if (errCode != IMAGE_SUCCESS) { 90 OH_LOG_ERROR(LOG_APP, "ImageReceiverNativeCTest set image receiver options size failed, errCode: %{public}d.", errCode); 91 OH_ImageReceiverOptions_Release(options); 92 return; 93 } 94 95 // 设置 OH_ImageReceiverOptions 的 capacity 属性。 96 errCode = OH_ImageReceiverOptions_SetCapacity(options, IMAGE_CAPACITY); 97 if (errCode != IMAGE_SUCCESS) { 98 OH_LOG_ERROR(LOG_APP, "ImageReceiverNativeCTest set image receiver options capacity failed, errCode: %{public}d.", errCode); 99 OH_ImageReceiverOptions_Release(options); 100 return; 101 } 102 103 // 读取 OH_ImageReceiverOptions 的 size 属性。该属性实际上不会生效,图片属性由生产者决定,如相机。 104 Image_Size imgSizeRead; 105 errCode = OH_ImageReceiverOptions_GetSize(options, &imgSizeRead); 106 if (errCode != IMAGE_SUCCESS) { 107 OH_LOG_ERROR(LOG_APP, "ImageReceiverNativeCTest get image receiver options size failed, errCode: %{public}d.", errCode); 108 OH_ImageReceiverOptions_Release(options); 109 return; 110 } 111 112 // 检查读取到的 size 值是否为设定值。该值实际上不会生效,图片宽高由生产者决定,如相机。 113 if (imgSizeRead.width != IMAGE_WIDTH || imgSizeRead.height != IMAGE_HEIGHT) { 114 OH_LOG_ERROR(LOG_APP, "ImageReceiverNativeCTest get image receiver options size failed, width: %{public}d, height: %{public}d.", imgSizeRead.width, imgSizeRead.height); 115 OH_ImageReceiverOptions_Release(options); 116 return; 117 } 118 119 // 读取 OH_ImageReceiverOptions 的 capacity 属性。 120 int32_t capacity = 0; 121 errCode = OH_ImageReceiverOptions_GetCapacity(options, &capacity); 122 if (errCode != IMAGE_SUCCESS) { 123 OH_LOG_ERROR(LOG_APP, "ImageReceiverNativeCTest get image receiver options capacity failed, errCode: %{public}d.", errCode); 124 OH_ImageReceiverOptions_Release(options); 125 return; 126 } 127 128 // 检查读取到的 capacity 值是否为设定值。 129 if (capacity != IMAGE_CAPACITY) { 130 OH_LOG_ERROR(LOG_APP, "ImageReceiverNativeCTest get image receiver options capacity failed, capacity: %{public}d.", capacity); 131 OH_ImageReceiverOptions_Release(options); 132 return; 133 } 134 135 // 创建 OH_ImageReceiverNative 实例。 136 errCode = OH_ImageReceiverNative_Create(options, &receiver); 137 if (errCode != IMAGE_SUCCESS) { 138 OH_LOG_ERROR(LOG_APP, "ImageReceiverNativeCTest create image receiver failed, errCode: %{public}d.", errCode); 139 OH_ImageReceiverOptions_Release(options); 140 return; 141 } 142 143 // 注册一个回调事件,每当接收到新的图片,该回调事件就会响应。 144 uint64_t surfaceID = 0; 145 errCode = OH_ImageReceiverNative_On(receiver, OnCallback); 146 if (errCode != IMAGE_SUCCESS) { 147 OH_LOG_ERROR(LOG_APP, "ImageReceiverNativeCTest image receiver on failed, errCode: %{public}d.", errCode); 148 OH_ImageReceiverOptions_Release(options); 149 OH_ImageReceiverNative_Release(receiver); 150 return; 151 } 152 153 // 读取 OH_ImageReceiverNative 的 surfaceID 属性。 154 errCode = OH_ImageReceiverNative_GetReceivingSurfaceId(receiver, &surfaceID); 155 if (errCode != IMAGE_SUCCESS) { 156 OH_LOG_ERROR(LOG_APP, "ImageReceiverNativeCTest get image receiver surfaceID failed, errCode: %{public}d.", errCode); 157 OH_ImageReceiverOptions_Release(options); 158 OH_ImageReceiverNative_Release(receiver); 159 return; 160 } 161 OH_LOG_INFO(LOG_APP, "ImageReceiverNativeCTest get image receiver surfaceID: %{public}lu.", surfaceID); 162 163 // 读取 OH_ImageReceiverNative 的 size 属性。 164 errCode = OH_ImageReceiverNative_GetSize(receiver, &imgSizeRead); 165 if (errCode != IMAGE_SUCCESS) { 166 OH_LOG_ERROR(LOG_APP, "ImageReceiverNativeCTest get image receiver size failed, errCode: %{public}d.", errCode); 167 OH_ImageReceiverOptions_Release(options); 168 OH_ImageReceiverNative_Release(receiver); 169 return; 170 } 171 OH_LOG_INFO(LOG_APP, "ImageReceiverNativeCTest get image receiver size: width = %{public}d, height = %{public}d.", imgSizeRead.width, imgSizeRead.height); 172 173 // 读取 OH_ImageReceiverNative 的 capacity 属性。 174 errCode = OH_ImageReceiverNative_GetCapacity(receiver, &capacity); 175 if (errCode != IMAGE_SUCCESS) { 176 OH_LOG_ERROR(LOG_APP, "ImageReceiverNativeCTest get image receiver capacity failed, errCode: %{public}d.", errCode); 177 OH_ImageReceiverOptions_Release(options); 178 OH_ImageReceiverNative_Release(receiver); 179 return; 180 } 181 OH_LOG_INFO(LOG_APP, "ImageReceiverNativeCTest get image receiver capacity: %{public}d.", capacity); 182 183 // 释放 OH_ImageReceiverOptions 实例。 184 errCode = OH_ImageReceiverOptions_Release(options); 185 if (errCode != IMAGE_SUCCESS) { 186 OH_LOG_ERROR(LOG_APP, "ImageReceiverNativeCTest release image receiver options failed, errCode: %{public}d.", errCode); 187 } 188} 189 190// 在合适时机释放ImageReceiverNative相关资源。 191static void ImageReceiverRelease() 192{ 193 // 关闭被 OH_ImageReceiverNative_On 开启的回调事件。 194 Image_ErrorCode errCode = OH_ImageReceiverNative_Off(receiver); 195 if (errCode != IMAGE_SUCCESS) { 196 OH_LOG_ERROR(LOG_APP, "ImageReceiverNativeCTest image receiver off failed, errCode: %{public}d.", errCode); 197 } 198 199 // 释放 OH_ImageReceiverOptions 实例。 200 errCode = OH_ImageReceiverNative_Release(receiver); 201 if (errCode != IMAGE_SUCCESS) { 202 OH_LOG_ERROR(LOG_APP, "ImageReceiverNativeCTest release image receiver failed, errCode: %{public}d.", errCode); 203 } 204} 205``` 206