1# 使用Image完成图片接收器
2
3图像接收类,用于获取组件surface id,接收最新的图片和读取下一张图片,以及释放ImageReceiver实例。
4
5## 开发步骤
6
7### 添加依赖
8
9在进行应用开发之前,开发者需要打开native工程的src/main/cpp/CMakeLists.txt,在target_link_libraries依赖中添加libace_napi.z.solibimage_ndk.z.solibimage_receiver_ndk.z.solibnative_image.so以及日志依赖libhilog_ndk.z.so10
11```txt
12target_link_libraries(entry PUBLIC libace_napi.z.so libhilog_ndk.z.so libimage_ndk.z.so libimage_receiver_ndk.z.so libnative_image.so)
13```
14
15### 添加接口映射
16
17打开src/main/cpp/hello.cpp文件,在Init函数中添加接口映射如下:
18
19```c++
20EXTERN_C_START
21static napi_value Init(napi_env env, napi_value exports)
22{
23    napi_property_descriptor desc[] = {
24        { "createFromReceiver", nullptr, createFromReceiver, nullptr, nullptr, nullptr, napi_default, nullptr },
25    };
26
27    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
28    return exports;
29}
30EXTERN_C_END
31```
32
33### 添加权限申请
34
35此处通过camera图片获取输入数据,需要申请权限ohos.permission.CAMERA,申请方式请参考[向用户申请授权](../../security/AccessToken/request-user-authorization.md)。
36
37### JS侧调用
38
391. 打开src\main\cpp\types\libentry\index.d.ts(其中libentry根据工程名生成),导入如下引用文件:
40
41    ```js
42    import { image } from '@kit.ImageKit';
43
44    export const createFromReceiver: (a: image.ImageReceiver) => image.Image;
45    ```
46
472. 打开src\main\ets\pages\index.ets,导入"libentry.so(根据工程名生成)",调用Native接口,传入JS的资源对象。示例如下:
48
49    ```js
50    import testNapi from 'libentry.so'
51    import { image } from '@kit.ImageKit';
52    import { abilityAccessCtrl } from '@kit.AbilityKit';
53    import { camera } from '@kit.CameraKit';
54
55    @Entry
56    @Component
57    struct Index {
58      private receiver: image.ImageReceiver | undefined = undefined;
59      func (){
60         let context = getContext()
61         abilityAccessCtrl.createAtManager().requestPermissionsFromUser(context,['ohos.permission.CAMERA']).then(async () => {
62            let cameraManager = await camera.getCameraManager(context);
63            // 获取支持的相机设备对象
64            let cameraDevices: Array<camera.CameraDevice> = cameraManager.getSupportedCameras();
65            if (cameraDevices.length <= 0) {
66            return;
67            }
68            // 获取对应相机设备的profiles
69            let profiles: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(cameraDevices[0], camera.SceneMode.NORMAL_PHOTO);
70            let previewProfiles: Array<camera.Profile> = profiles.previewProfiles;
71            if (previewProfiles.length <= 0) {
72            return;
73            }
74            let profileObj = previewProfiles[0];
75            this.receiver = image.createImageReceiver({width:profileObj.size.width, height:profileObj.size.height}, image.ImageFormat.JPEG, 8);
76            let receiverSurfaceId: string = await this.receiver.getReceivingSurfaceId();
77            // 创建预览流输出对象
78            let previewOutput: camera.PreviewOutput = cameraManager.createPreviewOutput(profileObj,receiverSurfaceId);
79            let cameraInput : camera.CameraInput = cameraManager.createCameraInput(cameraDevices[0]);
80            // 打开相机
81            await cameraInput.open();
82            // 会话流程
83            let session : camera.PhotoSession = cameraManager.createSession(camera.SceneMode.NORMAL_PHOTO) as camera.PhotoSession;
84            // 配置会话
85            session.beginConfig();
86            // 把cameraInput加入到会话
87            session.addInput(cameraInput);
88            // 把预览流加入到会话
89            session.addOutput(previewOutput);
90            // 提交配置信息
91            await session.commitConfig();
92            // 会话开始
93            await session.start();
94
95            this.receiver.on('imageArrival', () => {
96               let img : image.Image = testNapi.createFromReceiver(this.receiver);
97               img.release();
98            })
99
100         });
101      }
102
103      build() {
104         Row() {
105            Column() {
106            Button("start")
107               .width(100)
108               .height(100)
109               .onClick(() => {
110                  console.log("button click in");
111                  if (this.receiver == undefined) {
112                     this.func();
113                  }
114               })
115            }
116            .width('100%')
117         }
118         .height('100%')
119      }
120   }
121    ```
122
123### Native接口调用
124
125具体接口说明请参考[API文档](../../reference/apis-image-kit/image.md)。
126
127hello.cpp文件中获取JS的资源对象,并转为Native的资源对象,即可调用Native接口,调用方式示例代码如下:
128
129**添加引用文件**
130
131   ```c++
132
133      #include <multimedia/image_framework/image_mdk.h>
134      #include <multimedia/image_framework/image_receiver_mdk.h>
135      #include <malloc.h>
136      #include <hilog/log.h>
137
138      static napi_value createFromReceiver(napi_env env, napi_callback_info info)
139      {
140         size_t argc = 1;
141         napi_value args[2] = {nullptr};
142         napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
143         napi_valuetype valuetype0;
144         napi_typeof(env, args[0], &valuetype0);
145         napi_ref reference;
146         napi_create_reference(env, args[0], 1 ,&reference);
147         napi_value imgReceiver_js;
148         napi_get_reference_value(env, reference, &imgReceiver_js);
149
150         ImageReceiverNative * imgReceiver_c = OH_Image_Receiver_InitImageReceiverNative(env, imgReceiver_js);
151
152         int32_t capacity;
153         OH_Image_Receiver_GetCapacity(imgReceiver_c, &capacity);
154         OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "[receiver]", "capacity: %{public}d", capacity);
155         int32_t format;
156         OH_Image_Receiver_GetFormat(imgReceiver_c, &format);
157         OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "[receiver]", "format: %{public}d", format);
158         char * surfaceId = static_cast<char *>(malloc(sizeof(char)));
159         OH_Image_Receiver_GetReceivingSurfaceId(imgReceiver_c, surfaceId, sizeof(char));
160         OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "[receiver]", "surfaceId: %{public}c", surfaceId[0]);
161         OhosImageSize size;
162         OH_Image_Receiver_GetSize(imgReceiver_c, &size);
163         OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "[receiver]", "OH_Image_Receiver_GetSize  width: %{public}d, height:%{public}d", size.width, size.height);
164
165         int32_t ret;
166         napi_value nextImage;
167         // 或调用 OH_Image_Receiver_ReadNextImage(imgReceiver_c, &nextImage);
168         ret = OH_Image_Receiver_ReadLatestImage(imgReceiver_c, &nextImage);
169
170         ImageNative * nextImage_native = OH_Image_InitImageNative(env, nextImage);
171
172         OhosImageSize imageSize;
173         OH_Image_Size(nextImage_native, &imageSize);
174         OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "[receiver]", "OH_Image_Size  width: %{public}d, height:%{public}d", imageSize.width, imageSize.height);
175
176         OhosImageComponent imgComponent;
177         ret = OH_Image_GetComponent(nextImage_native, 4, &imgComponent); // 4=jpeg
178
179         uint8_t *img_buffer = imgComponent.byteBuffer;
180
181         ret = OH_Image_Release(nextImage_native);
182         ret = OH_Image_Receiver_Release(imgReceiver_c);
183         return nextImage;
184      }
185   ```
186