1 /*
2 * Copyright 2023 Unionman Technology Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <cstdio>
16 #include <cstring>
17 #include <opencv2/opencv.hpp>
18 #include "napi/native_api.h"
19 #include "napi/native_node_api.h"
20
resizeAndOverlay(const std::string & imagePath,const std::string & name,int newWidth,int newHeight)21 static std::string resizeAndOverlay(const std::string& imagePath, const std::string& name, int newWidth, int newHeight)
22 {
23 // 读取原始图像
24 cv::Mat originalImage = cv::imread(imagePath+"/"+name);
25 // 检查图像是否成功加载
26 if (originalImage.empty()) {
27 std::cerr << "Failed to load the image: " << imagePath << std::endl;
28 return (imagePath+"/"+name+"errogdrg");
29 }
30 // 调整图像大小
31 cv::Mat resizedImage;
32 cv::resize(originalImage, resizedImage, cv::Size(newWidth, newHeight));
33 // 保存结果图像,使用不同的文件名
34 cv::imwrite(imagePath+"/aaa.jpg", resizedImage);
35
36 return "succ";
37 }
38
39
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 struct LedAddOnData {
44 napi_async_work asyncWork = nullptr; // 异步工作项
45 napi_deferred deferred = nullptr; // 用于Promise的resolve、reject处理
46 napi_ref callback = nullptr; // 回调函数
47 char *args[2] = {nullptr};
48 int iargs[2] = {};
49 char *arr; // 2个输入参数
50 char *result; // 业务逻辑处理结果(返回值)
51 };
52 // 业务逻辑处理函数。
completeCBForPromise(napi_env env,napi_status status,void * data)53 static void completeCBForPromise(napi_env env, napi_status status, void *data)
54 {
55 LedAddOnData *addOnData = (LedAddOnData *)data;
56 napi_value result = nullptr;
57 napi_create_string_utf8(env, addOnData->result, strlen(addOnData->result), &result);
58 napi_resolve_deferred(env, addOnData->deferred, result);
59 free(addOnData->args[0]);
60 free(addOnData->result);
61 // 删除napi_ref对象
62 if (addOnData->callback != nullptr) {
63 napi_delete_reference(env, addOnData->callback);
64 }
65 // 删除异步工作项
66 napi_delete_async_work(env, addOnData->asyncWork);
67 delete addOnData;
68 }
69 // 业务逻辑处理函数,由worker线程池调度执行。
ShellExecuteCB(napi_env env,void * data)70 static void ShellExecuteCB(napi_env env, void *data)
71 {
72 LedAddOnData *addOnData = (LedAddOnData *)data;
73 int width = addOnData->iargs[0];
74 int height = addOnData->iargs[1];
75 std::string result = resizeAndOverlay(addOnData->args[0], addOnData->args[1], Width, Height);
76 addOnData->result = strdup(result.c_str()); // 使用 strdup 分配并复制字符串
77 }
opencvWithPromise(napi_env env,napi_callback_info info)78 static napi_value opencvWithPromise(napi_env env, napi_callback_info info)
79 {
80 // 期望从 ArkTS 侧获取的参数的数量,这里只接受一个参数
81 size_t argc = 4;
82 napi_value args[4] = {nullptr};
83 // 从 info 中获取从 ArkTS 侧传递过来的参数
84 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
85 // 创建promise
86 napi_value promise = nullptr;
87 napi_deferred deferred = nullptr;
88 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
89
90 // 异步工作项上下文用户数据,传递到异步工作项的execute、complete之间传递数据
91 auto addonData = new LedAddOnData {
92 .asyncWork = nullptr,
93 .deferred = deferred,
94 };
95
96 // 将被收到的参数传入
97 size_t strSize = 0;
98 napi_get_value_string_utf8(env, args[0], nullptr, 0, &strSize);
99 char *strValue = new char[strSize + 1];
100 napi_status status1;
101 size_t strSize1 = 0;
102 status1 = napi_get_value_string_utf8(env, args[0], strValue, strSize + 1, &strSize1);
103 addonData->args[0] = (char *)malloc(strlen(strValue) + 1);
104 addonData->args[0] = strdup(strValue); // 使用 strdup 分配并复制字符串
105
106 size_t strSize2 = 0;
107 napi_get_value_string_utf8(env, args[1], nullptr, 0, &strSize2);
108 char *strValue1 = new char[strSize2 + 1];
109 napi_status status2;
110 size_t strSize3 = 0;
111 status2 = napi_get_value_string_utf8(env, args[1], strValue1, strSize + 1, &strSize3);
112 addonData->args[1] = (char *)malloc(strlen(strValue1) + 1);
113 addonData->args[1] = strdup(strValue1); // 使用 strdup 分配并复制字符串
114
115 napi_get_value_int32(env, args[2L], &addonData->iargs[0]);
116 napi_get_value_int32(env, args[3L], &addonData->iargs[1]);
117 // 创建async work,创建成功后通过最后一个参数(addonData->asyncWork)返回asyncwork的handle
118 napi_value resourceName = nullptr;
119 napi_create_string_utf8(env, "ShellExecuteCB", NAPI_AUTO_LENGTH, &resourceName);
120 napi_create_async_work(env, nullptr, resourceName, ShellExecuteCB, completeCBForPromise, (void *)addonData,
121 &addonData->asyncWork);
122 // 将刚创建的async work加到队列,由底层去调度执行
123 napi_queue_async_work(env, addonData->asyncWork);
124 // 返回promise
125 return promise;
126 }
127 /* 以上为实现异步计算接下来10s内温度,可设置为传参类型 */
128
129 /*
130 * 注册接口
131 */
registerdeviceinfoApis(napi_env env,napi_value exports)132 static napi_value registerdeviceinfoApis(napi_env env, napi_value exports)
133 {
134 napi_property_descriptor desc[] = {
135 DECLARE_NAPI_FUNCTION("opencvWithPromise", opencvWithPromise),
136 };
137 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
138 return exports;
139 }
140 /*
141 * 模块定义
142 */
143 static napi_module writeShellnapiModule = {
144 .nm_version = 1,
145 .nm_flags = 0,
146 .nm_filename = nullptr,
147 .nm_register_func = registerdeviceinfoApis,
148 .nm_modname = "opencvnapi", // 模块名
149 .nm_priv = ((void *)0),
150 .reserved = {0},
151 };
152 #ifdef __cplusplus
153 }
154 #endif
155 /*
156 * 注册模块
157 */
RegisterModule(void)158 extern "C" __attribute__((constructor)) void RegisterModule(void)
159 {
160 napi_module_register(&writeShellnapiModule); // 接口注册函数
161 }
162