• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.solibimage_receiver.solibnative_image.so以及日志依赖libhilog_ndk.z.so19
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.cppnapi_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