1 /*
2 * Copyright (c) 2025 Huawei Device 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
16 #include <strstream>
17 #include <map>
18 // [Start image_effect_include_module]
19 #include <multimedia/image_effect/image_effect.h>
20 #include <multimedia/image_effect/image_effect_filter.h>
21 #include <multimedia/image_effect/image_effect_errors.h>
22 // [End image_effect_include_module]
23 #include <multimedia/image_framework/image_pixel_map_mdk.h>
24 #include <native_buffer/native_buffer.h>
25 #include "logging.h"
26 #include "image_edit.h"
27 #include "utils/common_utils.h"
28 #include "utils/pixelmap_helper.h"
29 #include "utils/json_utils.h"
30
31 struct FilterArrayData {
32 std::string name;
33 int value;
34 };
35
36 struct PixelmapInfo {
37 uint32_t width = 0;
38 uint32_t height = 0;
39 int32_t format = PIXEL_FORMAT::PIXEL_FORMAT_UNKNOWN;
40 uint32_t rowStride = 0;
41 };
42
43 static ImageEffect_FilterDelegate delegateBrightness;
44 static ImageEffect_FilterDelegate delegateCrop;
45
46 std::vector<std::vector<FilterArrayData>> GetFilters(napi_env env, napi_value arg);
47
48 OH_EffectFilter *AddFilter(OH_ImageEffect *imageEffect, const char *filterName);
49 napi_value SetFilterValue(OH_EffectFilter *filter, const char *filterName, float filterValue,
50 OH_PixelmapNative *pixelmap);
51 void AddFilterSingle(const char *filterName, float filterValue, OH_PixelmapNative *inputPixelmap,
52 OH_PixelmapNative *outputPixelmap);
53 PixelmapInfo GetPixelmapInfo(OH_PixelmapNative *pixelmap);
54
55 const double PI = 3.14159265;
56
57 // 滤镜数据范围
58 const float_t DATA_VALUE_MIN = -100.0;
59 const float_t DATA_VALUE_MAX = 100.0;
60
61 // 预期参数数量
62 constexpr int EXPECTED_ARGS_ZERO = 0;
63 constexpr int EXPECTED_ARGS_ONE = 1;
64 constexpr int EXPECTED_ARGS_TWO = 2;
65
66 // AREA信息索引下标
67 constexpr int AREA_INFO_ZERO = 0;
68 constexpr int AREA_INFO_ONE = 1;
69 constexpr int AREA_INFO_TWO = 2;
70 constexpr int AREA_INFO_THREE = 3;
71
72 // RBGA8888格式,一个像素点由四个字节组成
73 constexpr int RGB_IDX_ZERO = 0;
74 constexpr int RGB_IDX_THREE = 3;
75
76 // RGB颜色范围
77 constexpr int RBG_MIN = 0;
78 constexpr int RBG_MAX = 255;
79
80 OH_ImageEffect* ImageEdit::imageEffect_ = nullptr;
81
~ImageEdit()82 ImageEdit::~ImageEdit()
83 {
84 if (imageEffect_ != nullptr) {
85 OH_ImageEffect_Release(imageEffect_);
86 imageEffect_ = nullptr;
87 }
88 }
89
PixelMapFilterStart(napi_env env,napi_callback_info info)90 napi_value ImageEdit::PixelMapFilterStart(napi_env env, napi_callback_info info)
91 {
92 napi_value result = nullptr;
93 napi_get_boolean(env, false, &result);
94
95 size_t argc = EXPECTED_ARGS_TWO;
96 napi_value args[EXPECTED_ARGS_TWO] = {nullptr};
97 napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
98 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_get_cb_info fail! status = %{public}d", status);
99
100 std::string path = CommonUtils::GetStringArgument(env, args[EXPECTED_ARGS_ZERO]);
101 std::vector<std::vector<FilterArrayData>> filters = GetFilters(env, args[EXPECTED_ARGS_ONE]);
102
103 // [Start image_effect_instance_creation]
104 OH_ImageEffect *imageEffect = OH_ImageEffect_Create("imageEdit");
105 // [End image_effect_instance_creation]
106 CHECK_AND_RETURN_RET_LOG(imageEffect != nullptr, result, "OH_ImageEffect_Create fail!");
107 std::shared_ptr<OH_ImageEffect> imageEffectPtr(
108 imageEffect, [](OH_ImageEffect *imageEffect) { OH_ImageEffect_Release(imageEffect); });
109
110 std::shared_ptr<OH_PixelmapNative> pixelmapNativePtr = PixelMapHelper::Decode(path);
111 CHECK_AND_RETURN_RET_LOG(pixelmapNativePtr != nullptr, result, "Decode path fail! path=%{public}s", path.c_str());
112
113 if (filters.size() == 1 && (strcmp(filters[0][0].name.c_str(), OH_EFFECT_BRIGHTNESS_FILTER) == 0 ||
114 strcmp(filters[0][0].name.c_str(), OH_EFFECT_CONTRAST_FILTER) == 0)) {
115 std::shared_ptr<OH_PixelmapNative> outputpixelmapNativePtr = PixelMapHelper::Decode(path);
116 CHECK_AND_RETURN_RET_LOG(outputpixelmapNativePtr != nullptr, result, "Decode path fail! path=%{public}s",
117 path.c_str());
118
119 AddFilterSingle(filters[0][0].name.c_str(), filters[0][0].value, pixelmapNativePtr.get(),
120 outputpixelmapNativePtr.get());
121
122 bool encodeRes = PixelMapHelper::Encode(outputpixelmapNativePtr.get(), path);
123 CHECK_AND_RETURN_RET_LOG(encodeRes, result, "Encode path fail! path=%{public}s", path.c_str());
124
125 napi_get_boolean(env, true, &result);
126 return result;
127 }
128
129 for (int i = 0; i < filters.size(); i++) {
130 OH_EffectFilter *filter = AddFilter(imageEffectPtr.get(), filters[i][0].name.c_str());
131 CHECK_AND_RETURN_RET_LOG(filter != nullptr, result, "OH_ImageEffect_AddFilter fail!");
132 LOG_I("%{public}s : %{public}d", filters[i][0].name.c_str(), filters[i][0].value);
133 SetFilterValue(filter, filters[i][0].name.c_str(), filters[i][0].value, pixelmapNativePtr.get());
134 }
135
136 // [Start image_effect_pixelmap_native]
137 ImageEffect_ErrorCode errorCode = OH_ImageEffect_SetInputPixelmap(imageEffectPtr.get(), pixelmapNativePtr.get());
138 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, result,
139 "OH_ImageEffect_SetInputPixelMap fail! errorCode = %{public}d", errorCode);
140
141 // 设置输出的Pixelmap(可选),不调用该接口时会在输入Pixelmap上直接生效滤镜效果。
142 errorCode = OH_ImageEffect_SetOutputPixelmap(imageEffectPtr.get(), pixelmapNativePtr.get());
143 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, result,
144 "OH_ImageEffect_SetOutputPixelmap fail!");
145 // [End image_effect_pixelmap_native]
146
147 // [Start image_effect_start]
148 errorCode = OH_ImageEffect_Start(imageEffectPtr.get());
149 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, result,
150 "OH_ImageEffect_Start fail! errorCode = %{public}d", errorCode);
151 // [End image_effect_start]
152
153 // [Start image_effect_save]
154 // (可选 序列化效果器)
155 char *imageinfo = nullptr;
156 errorCode = OH_ImageEffect_Save(imageEffect, &imageinfo);
157 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, result, "OH_ImageEffect_Save fail!");
158 // [End image_effect_save]
159
160 bool encodeRes = PixelMapHelper::Encode(pixelmapNativePtr.get(), path);
161 CHECK_AND_RETURN_RET_LOG(encodeRes, result, "Encode path fail! path=%{public}s", path.c_str());
162
163 napi_get_boolean(env, true, &result);
164 return result;
165 }
166
NativeBufferFilterStart(napi_env env,napi_callback_info info)167 napi_value ImageEdit::NativeBufferFilterStart(napi_env env, napi_callback_info info)
168 {
169 napi_value result = nullptr;
170 napi_get_boolean(env, false, &result);
171
172 size_t argc = EXPECTED_ARGS_ONE;
173 napi_value args[EXPECTED_ARGS_ONE] = {nullptr};
174 napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
175 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_get_cb_info fail! status = %{public}d", status);
176
177 std::vector<std::vector<FilterArrayData>> filters = GetFilters(env, args[EXPECTED_ARGS_ZERO]);
178
179 OH_ImageEffect *imageEffect = OH_ImageEffect_Create("imageEdit");
180 CHECK_AND_RETURN_RET_LOG(imageEffect != nullptr, result, "OH_ImageEffect_Create fail!");
181 std::shared_ptr<OH_ImageEffect> imageEffectPtr(imageEffect, [](OH_ImageEffect *imageEffect) {
182 // [Start image_effect_release]
183 ImageEffect_ErrorCode errorCode = OH_ImageEffect_Release(imageEffect);
184 CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_Release fail!");
185 // [End image_effect_release]
186 });
187
188 OH_NativeBuffer_Config config{
189 .width = 0x100,
190 .height = 0x100,
191 .format = NATIVEBUFFER_PIXEL_FMT_RGBA_8888,
192 .usage = NATIVEBUFFER_USAGE_ALIGNMENT_512,
193 };
194
195 for (int i = 0; i < filters.size(); i++) {
196 OH_EffectFilter *filter = AddFilter(imageEffectPtr.get(), filters[i][0].name.c_str());
197 CHECK_AND_RETURN_RET_LOG(filter != nullptr, result, "OH_ImageEffect_AddFilter fail!");
198 SetFilterValue(filter, filters[i][0].name.c_str(), filters[i][0].value, nullptr);
199 }
200
201 OH_NativeBuffer *inputNativeBuffer = OH_NativeBuffer_Alloc(&config);
202 CHECK_AND_RETURN_RET_LOG(inputNativeBuffer != nullptr, result, "OH_NativeBuffer_Alloc Failed!");
203
204 OH_NativeBuffer *outputNativeBuffer = inputNativeBuffer;
205
206 // [Start image_effect_native_buffer]
207 // 设置输入的NativeBuffer。
208 ImageEffect_ErrorCode errorCode = OH_ImageEffect_SetInputNativeBuffer(imageEffect, inputNativeBuffer);
209 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, result,
210 "OH_ImageEffect_SetInputNativeBuffer fail!");
211
212 // 设置输出的NativeBuffer(可选),不调用该接口时会在输入NativeBuffer上直接生效滤镜效果。
213 errorCode = OH_ImageEffect_SetOutputNativeBuffer(imageEffect, outputNativeBuffer);
214 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, result,
215 "OH_ImageEffect_SetOutputNativeBuffer fail!");
216 // [End image_effect_native_buffer]
217
218 errorCode = OH_ImageEffect_Start(imageEffectPtr.get());
219 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, result,
220 "OH_ImageEffect_Start fail! errorCode = %{public}d", errorCode);
221
222 // (可选 序列化效果器)
223 char *imageinfo = nullptr;
224 errorCode = OH_ImageEffect_Save(imageEffect, &imageinfo);
225 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, result, "OH_ImageEffect_Save fail!");
226
227 napi_get_boolean(env, true, &result);
228 return result;
229 }
230
URIFilterStart(napi_env env,napi_callback_info info)231 napi_value ImageEdit::URIFilterStart(napi_env env, napi_callback_info info)
232 {
233 napi_value result = nullptr;
234 napi_get_boolean(env, false, &result);
235
236 size_t argc = EXPECTED_ARGS_TWO;
237 napi_value args[EXPECTED_ARGS_TWO] = {nullptr};
238 napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
239 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_get_cb_info fail! status = %{public}d", status);
240
241 std::string path = CommonUtils::GetStringArgument(env, args[EXPECTED_ARGS_ZERO]);
242 std::vector<std::vector<FilterArrayData>> filters = GetFilters(env, args[EXPECTED_ARGS_ONE]);
243
244 OH_ImageEffect *imageEffect = OH_ImageEffect_Create("imageEdit");
245 CHECK_AND_RETURN_RET_LOG(imageEffect != nullptr, result, "OH_ImageEffect_Create fail!");
246 std::shared_ptr<OH_ImageEffect> imageEffectPtr(imageEffect, [](OH_ImageEffect *imageEffect) {
247 ImageEffect_ErrorCode errorCode = OH_ImageEffect_Release(imageEffect);
248 CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_ImageEffect_Release fail!");
249 });
250
251 std::shared_ptr<OH_PixelmapNative> pixelmapNativePtr = PixelMapHelper::Decode(path);
252 CHECK_AND_RETURN_RET_LOG(pixelmapNativePtr != nullptr, result, "Decode path fail! path=%{public}s", path.c_str());
253
254 for (int i = 0; i < filters.size(); i++) {
255 OH_EffectFilter *filter = AddFilter(imageEffectPtr.get(), filters[i][0].name.c_str());
256 CHECK_AND_RETURN_RET_LOG(filter != nullptr, result, "OH_ImageEffect_AddFilter fail!");
257 SetFilterValue(filter, filters[i][0].name.c_str(), filters[i][0].value, pixelmapNativePtr.get());
258 }
259
260 // [Start image_effect_url]
261 // 设置输入的URI。
262 ImageEffect_ErrorCode errorCode = OH_ImageEffect_SetInputUri(imageEffectPtr.get(), path.c_str());
263 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, result,
264 "OH_ImageEffect_SetInputPixelMap fail! errorCode = %{public}d", errorCode);
265
266 // 设置输出的URI(可选),不调用该接口时会在输入URI上直接生效滤镜效果。
267 errorCode = OH_ImageEffect_SetOutputUri(imageEffect, path.c_str());
268 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, result,
269 "OH_ImageEffect_SetOutputUri fail!");
270 // [End image_effect_url]
271
272 errorCode = OH_ImageEffect_Start(imageEffectPtr.get());
273 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, result,
274 "OH_ImageEffect_Start fail! errorCode = %{public}d", errorCode);
275
276 // (可选 序列化效果器)
277 char *imageinfo = nullptr;
278 errorCode = OH_ImageEffect_Save(imageEffect, &imageinfo);
279 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, result, "OH_ImageEffect_Save fail!");
280
281 napi_get_boolean(env, true, &result);
282 return result;
283 }
284
SurfaceFilterStart(napi_env env,napi_callback_info info)285 napi_value ImageEdit::SurfaceFilterStart(napi_env env, napi_callback_info info)
286 {
287 napi_value result = nullptr;
288 napi_get_boolean(env, false, &result);
289
290 size_t argc = EXPECTED_ARGS_ONE;
291 napi_value args[EXPECTED_ARGS_ONE] = {nullptr};
292 napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
293 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_get_cb_info fail! status = %{public}d", status);
294
295 std::vector<std::vector<FilterArrayData>> filters = GetFilters(env, args[EXPECTED_ARGS_ZERO]);
296
297 OH_ImageEffect *imageEffect = ImageEdit::imageEffect_;
298 CHECK_AND_RETURN_RET_LOG(imageEffect != nullptr, result, "imageEffect is nullptr!");
299
300 for (int i = 0; i < filters.size(); i++) {
301 OH_EffectFilter *filter = AddFilter(imageEffect, filters[i][0].name.c_str());
302 CHECK_AND_RETURN_RET_LOG(filter != nullptr, result, "OH_ImageEffect_AddFilter fail!");
303 SetFilterValue(filter, filters[i][0].name.c_str(), filters[i][0].value, nullptr);
304 }
305
306 // 执行生效滤镜效果。
307 ImageEffect_ErrorCode errorCode = OH_ImageEffect_Start(imageEffect);
308 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, result,
309 "OH_ImageEffect_Start fail! %{public}d", errorCode);
310 napi_get_boolean(env, true, &result);
311 return result;
312 }
313
SurfaceFilterStop(napi_env env,napi_callback_info info)314 napi_value ImageEdit::SurfaceFilterStop(napi_env env, napi_callback_info info)
315 {
316 napi_value result = nullptr;
317 napi_get_boolean(env, false, &result);
318
319 OH_ImageEffect *imageEffect = ImageEdit::imageEffect_;
320 CHECK_AND_RETURN_RET_LOG(imageEffect != nullptr, result, "imageEffect is nullptr!");
321
322 // [Start image_effect_stop]
323 // 停止生效滤镜效果。
324 ImageEffect_ErrorCode errorCode = OH_ImageEffect_Stop(imageEffect);
325 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, result, "OH_ImageEffect_Stop fail!");
326 // [End image_effect_stop]
327
328 napi_get_boolean(env, true, &result);
329 return result;
330 }
331
AddFilter(OH_ImageEffect * imageEffect,const char * filterName)332 OH_EffectFilter *AddFilter(OH_ImageEffect *imageEffect, const char *filterName)
333 {
334 // [Start image_effect_add_filter]
335 OH_EffectFilter *filter = OH_ImageEffect_AddFilter(imageEffect, filterName);
336 CHECK_AND_RETURN_RET_LOG(filter != nullptr, filter, "OH_ImageEffect_AddFilter fail!");
337 // [End image_effect_add_filter]
338 return filter;
339 }
340
AddFilterSingle(const char * filterName,float filterValue,OH_PixelmapNative * inputPixelmap,OH_PixelmapNative * outputPixelmap)341 void AddFilterSingle(const char *filterName, float filterValue, OH_PixelmapNative *inputPixelmap,
342 OH_PixelmapNative *outputPixelmap)
343 {
344 // [Start image_effect_create_filter]
345 // 创建滤镜。比如:创建对比度效果器。
346 OH_EffectFilter *filter = OH_EffectFilter_Create(filterName);
347 CHECK_AND_RETURN_LOG(filter != nullptr, "OH_EffectFilter_Create fail!");
348 // [End image_effect_create_filter]
349
350 // [Start image_effect_set_filter_value]
351 // 设置滤镜参数, 滤镜强度设置为传入参数。
352 ImageEffect_Any value;
353 value.dataType = ImageEffect_DataType::EFFECT_DATA_TYPE_FLOAT;
354 value.dataValue.floatValue = static_cast<float>(filterValue);
355 ImageEffect_ErrorCode errorCode = OH_EffectFilter_SetValue(filter, OH_EFFECT_FILTER_INTENSITY_KEY, &value);
356 CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_EffectFilter_SetValue fail!");
357 // [End image_effect_set_filter_value]
358
359 // [Start image_effect_filter_render]
360 // 生效滤镜效果。
361 errorCode = OH_EffectFilter_Render(filter, inputPixelmap, outputPixelmap);
362 CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_EffectFilter_Render fail!");
363 // [End image_effect_filter_render]
364
365 // [Start image_effect_filter_release]
366 // 销毁滤镜实例。
367 errorCode = OH_EffectFilter_Release(filter);
368 CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, "OH_EffectFilter_Release fail!");
369 // [End image_effect_filter_release]
370 }
371
GetPixelmapInfo(OH_PixelmapNative * pixelmap)372 PixelmapInfo GetPixelmapInfo(OH_PixelmapNative *pixelmap)
373 {
374 OH_Pixelmap_ImageInfo *imageInfo = nullptr;
375 OH_PixelmapImageInfo_Create(&imageInfo);
376 OH_PixelmapNative_GetImageInfo(pixelmap, imageInfo);
377 PixelmapInfo info;
378 OH_PixelmapImageInfo_GetWidth(imageInfo, &info.width);
379 OH_PixelmapImageInfo_GetHeight(imageInfo, &info.height);
380 OH_PixelmapImageInfo_GetPixelFormat(imageInfo, &info.format);
381 OH_PixelmapImageInfo_GetRowStride(imageInfo, &info.rowStride);
382 OH_PixelmapImageInfo_Release(imageInfo);
383
384 return info;
385 }
386
SetFilterValue(OH_EffectFilter * filter,const char * filterName,float filterValue,OH_PixelmapNative * pixelmap)387 napi_value SetFilterValue(OH_EffectFilter *filter, const char *filterName, float filterValue,
388 OH_PixelmapNative *pixelmap)
389 {
390 napi_value result;
391 ImageEffect_Any value;
392 std::string key;
393
394 if (strcmp(filterName, OH_EFFECT_CROP_FILTER) == 0) {
395 CHECK_AND_RETURN_RET_LOG(pixelmap != nullptr, result, "pixelmap nullptr!");
396 PixelmapInfo pixelMapInfo = GetPixelmapInfo(pixelmap);
397 uint32_t *areaInfo = new uint32_t[4];
398 CHECK_AND_RETURN_RET_LOG(areaInfo, result, "areaInfo fail!");
399 areaInfo[AREA_INFO_ZERO] = pixelMapInfo.width / 100.f * (100.f - static_cast<int>(filterValue));
400 areaInfo[AREA_INFO_ONE] = pixelMapInfo.height / 100.f * (100.f - static_cast<int>(filterValue));
401 areaInfo[AREA_INFO_TWO] = pixelMapInfo.width;
402 areaInfo[AREA_INFO_THREE] = pixelMapInfo.height;
403 value.dataType = ImageEffect_DataType::EFFECT_DATA_TYPE_PTR;
404 value.dataValue.ptrValue = areaInfo;
405 key = OH_EFFECT_FILTER_REGION_KEY;
406 } else if (strcmp(filterName, "CustomBrightness") == 0) {
407 value.dataType = ImageEffect_DataType::EFFECT_DATA_TYPE_FLOAT;
408 value.dataValue.floatValue = filterValue;
409 key = "brightness";
410 } else if (strcmp(filterName, "CustomCrop") == 0) {
411 value.dataType = ImageEffect_DataType::EFFECT_DATA_TYPE_FLOAT;
412 value.dataValue.floatValue = filterValue;
413 key = "crop";
414 } else {
415 value.dataType = ImageEffect_DataType::EFFECT_DATA_TYPE_FLOAT;
416 value.dataValue.floatValue = filterValue;
417 key = OH_EFFECT_FILTER_INTENSITY_KEY;
418 }
419 ImageEffect_ErrorCode errorCode = OH_EffectFilter_SetValue(filter, key.c_str(), &value);
420 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, nullptr,
421 "OH_EffectFilter_SetValue fail! errorCode = %{public}d", errorCode);
422 return result;
423 }
424
GetNapiArrayLength(napi_env env,napi_value element)425 std::pair<napi_status, uint32_t> GetNapiArrayLength(napi_env env, napi_value element)
426 {
427 uint32_t length = 0;
428 napi_status status = napi_get_array_length(env, element, &length);
429 return std::make_pair(status, length);
430 }
431
HandleStringType(napi_env env,napi_value childElement,napi_status & status)432 std::string HandleStringType(napi_env env, napi_value childElement, napi_status &status)
433 {
434 std::string name;
435
436 size_t bufferLength = 0;
437 status = napi_get_value_string_utf8(env, childElement, nullptr, 0, &bufferLength);
438 CHECK_AND_RETURN_RET_LOG(status == napi_ok && bufferLength > 0, name,
439 "GetFilters napi_get_value_string_utf8 fail! status = %{public}d", status);
440 char *buffer = nullptr;
441 buffer = reinterpret_cast<char *>(malloc((bufferLength + 1) * sizeof(char)));
442 status = napi_get_value_string_utf8(env, childElement, buffer, bufferLength + 1, &bufferLength);
443 if (status == napi_ok) {
444 name = buffer;
445 }
446 free(buffer);
447 return name;
448 }
449
HandleNumberType(napi_env env,napi_value childElement,napi_status & status)450 int HandleNumberType(napi_env env, napi_value childElement, napi_status &status)
451 {
452 int32_t result = 0;
453 status = napi_get_value_int32(env, childElement, &result);
454 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "GetFilters napi_get_value_int32 fail! status = %{public}d",
455 status);
456 return result;
457 }
458
GetFilters(napi_env env,napi_value arg)459 std::vector<std::vector<FilterArrayData>> GetFilters(napi_env env, napi_value arg)
460 {
461 std::vector<std::vector<FilterArrayData>> data;
462 napi_status status;
463
464 bool is_array;
465 status = napi_is_array(env, arg, &is_array);
466 CHECK_AND_RETURN_RET_LOG(is_array == true, data, "GetFilters napi_is_array fail! status=%{public}d", status);
467
468 auto array_length = GetNapiArrayLength(env, arg);
469 CHECK_AND_RETURN_RET_LOG(array_length.first == napi_ok, data,
470 "GetFilters napi_get_array_length fail! status=%{public}d", array_length.first);
471
472 for (uint32_t i = 0; i < array_length.second; i++) {
473 napi_value element;
474 status = napi_get_element(env, arg, i, &element);
475 CHECK_AND_RETURN_RET_LOG(status == napi_ok, data, "GetFilters napi_get_element fail! status=%{public}d",
476 status);
477
478 auto child_length = GetNapiArrayLength(env, element);
479 CHECK_AND_RETURN_RET_LOG(child_length.first == napi_ok, data,
480 "GetFilters child napi_get_array_length fail! status=%{public}d", child_length.first);
481
482 std::vector<FilterArrayData> row;
483 FilterArrayData filterArrayData;
484 for (uint32_t j = 0; j < child_length.second; j++) {
485 napi_value childElement;
486 status = napi_get_element(env, element, j, &childElement);
487
488 napi_valuetype valueType;
489 status = napi_typeof(env, childElement, &valueType);
490 CHECK_AND_RETURN_RET_LOG(status == napi_ok, data,
491 "GetFilters child napi_typeof fail! status=%{public}d, value=%{public}d", status,
492 valueType);
493
494 if (valueType == napi_string) {
495 filterArrayData.name = HandleStringType(env, childElement, status);
496 } else if (valueType == napi_number) {
497 filterArrayData.value = HandleNumberType(env, childElement, status);
498 }
499 }
500 row.push_back(filterArrayData);
501 data.push_back(row);
502 }
503
504 return data;
505 }
506
LookupFilterInfo(napi_env env,napi_callback_info info)507 napi_value ImageEdit::LookupFilterInfo(napi_env env, napi_callback_info info)
508 {
509 napi_value result = nullptr;
510 napi_get_undefined(env, &result);
511 size_t argc = EXPECTED_ARGS_ONE;
512 napi_value args[EXPECTED_ARGS_ONE] = {nullptr};
513 napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
514 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_get_cb_info fail! status = %{public}d", status);
515 std::string filterName = CommonUtils::GetStringArgument(env, args[EXPECTED_ARGS_ZERO]);
516
517 // [Start image_effect_lookup_filter_info_by_name]
518 OH_EffectFilterInfo *filterInfo = OH_EffectFilterInfo_Create();
519 // 示例代码: 传入nullptr的format, 获取OH_Formats的size
520 ImageEffect_ErrorCode errorCode = OH_EffectFilter_LookupFilterInfo(filterName.c_str(), filterInfo);
521 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, result,
522 "OH_EffectFilter_LookupFilterInfo fail! errorCode = %{public}d", errorCode);
523
524 char *name = nullptr;
525 OH_EffectFilterInfo_GetFilterName(filterInfo, &name);
526
527 uint32_t supportedBufferTypesCount = 0;
528 ImageEffect_BufferType *bufferTypeArray = nullptr;
529 OH_EffectFilterInfo_GetSupportedBufferTypes(filterInfo, &supportedBufferTypesCount, &bufferTypeArray);
530
531 uint32_t supportedFormatsCount = 0;
532 ImageEffect_Format *formatArray = nullptr;
533 OH_EffectFilterInfo_GetSupportedFormats(filterInfo, &supportedFormatsCount, &formatArray);
534
535 LOG_I("LookupFilterInfo: name=%{public}s, bufferTypesCount=%{public}d, formatsCount=%{public}d", name,
536 supportedBufferTypesCount, supportedFormatsCount);
537
538 std::string infoStr = CommonUtils::EffectInfoToString(filterInfo);
539 LOG_I("LookupFilterInfo:%{public}s", infoStr.c_str());
540 status = napi_create_string_utf8(env, infoStr.c_str(), strlen(infoStr.c_str()), &result);
541 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_create_string_utf8 fail!");
542
543 OH_EffectFilterInfo_Release(filterInfo);
544 // [End image_effect_lookup_filter_info_by_name]
545 return result;
546 }
547
548 // [Start image_effect_buffer_info]
549 // 图像信息结构体。
550 struct EffectBufferInfo {
551 void *addr = nullptr;
552 int32_t width = 0;
553 int32_t height = 0;
554 int32_t rowSize = 0;
555 ImageEffect_Format format = ImageEffect_Format::EFFECT_PIXEL_FORMAT_UNKNOWN;
556 };
557 // [End image_effect_buffer_info]
558
ApplyCustomBrightnessAlgo(OH_EffectFilter * filter,EffectBufferInfo inputBufferInfo)559 void ApplyCustomBrightnessAlgo(OH_EffectFilter *filter, EffectBufferInfo inputBufferInfo)
560 {
561 ImageEffect_Any value;
562 ImageEffect_ErrorCode errorCode = OH_EffectFilter_GetValue(filter, "brightness", &value);
563 CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS,
564 "OH_EffectFilter_GetValue fail! 11 %{public}d", errorCode);
565
566 float brightnessIncrement = value.dataValue.floatValue;
567
568 // 获取图像的宽度和高度
569 int32_t width = inputBufferInfo.width;
570 int32_t height = inputBufferInfo.height;
571 int32_t rowSize = inputBufferInfo.rowSize;
572 ImageEffect_Format format = inputBufferInfo.format;
573
574 // 检查图片格式是否为RGBA8888
575 CHECK_AND_RETURN_LOG(format == ImageEffect_Format::EFFECT_PIXEL_FORMAT_RGBA8888,
576 "Unsupported image format: %{public}d", format);
577
578 // 获取图像数据指针
579 uint8_t *pixelData = static_cast<uint8_t *>(inputBufferInfo.addr);
580 // 遍历每个像素
581 for (int y = 0; y < height; ++y) {
582 for (int x = 0; x < width; ++x) {
583 // 计算当前像素的起始地址
584 uint8_t *pixel = pixelData + y * rowSize + x * 4;
585 // 增加亮度值,最小值为0,最大值为255
586 for (int i = RGB_IDX_ZERO; i < RGB_IDX_THREE; ++i) {
587 int tempPixel = static_cast<int>(pixel[i]) + static_cast<int>(brightnessIncrement);
588 pixel[i] = std::max(RBG_MIN, std::min(RBG_MAX, tempPixel));
589 }
590 }
591 }
592 }
593
594 // [Start image_effect_render_brightness]
RenderBrightness(OH_EffectFilter * filter,OH_EffectBufferInfo * info,OH_EffectFilterDelegate_PushData pushData)595 bool RenderBrightness(OH_EffectFilter *filter, OH_EffectBufferInfo *info, OH_EffectFilterDelegate_PushData pushData)
596 {
597 // 获取图像信息具体参数。
598 EffectBufferInfo inputBufferInfo;
599 OH_EffectBufferInfo_GetAddr(info, &inputBufferInfo.addr);
600 OH_EffectBufferInfo_GetWidth(info, &inputBufferInfo.width);
601 OH_EffectBufferInfo_GetHeight(info, &inputBufferInfo.height);
602 OH_EffectBufferInfo_GetRowSize(info, &inputBufferInfo.rowSize);
603 OH_EffectBufferInfo_GetEffectFormat(info, &inputBufferInfo.format);
604
605 // 调用自定义滤镜算法。
606 ApplyCustomBrightnessAlgo(filter, inputBufferInfo);
607
608 // 编辑完成后调用pushData直接传递原图。
609 pushData(filter, info);
610 return true;
611 }
612 // [End image_effect_render_brightness]
613
ApplyCustomCropAlgo(OH_EffectFilter * filter,EffectBufferInfo inputBufferInfo,EffectBufferInfo & outputBufferInfo)614 void ApplyCustomCropAlgo(OH_EffectFilter *filter, EffectBufferInfo inputBufferInfo,
615 EffectBufferInfo &outputBufferInfo)
616 {
617 ImageEffect_Any value;
618 ImageEffect_ErrorCode errorCode = OH_EffectFilter_GetValue(filter, "crop", &value);
619 CHECK_AND_RETURN_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS,
620 "OH_EffectFilter_GetValue fail! 22 %{public}d", errorCode);
621
622 float cropIncrement = value.dataValue.floatValue;
623
624 // 计算新的高度
625 int32_t newHeight = static_cast<int32_t>(inputBufferInfo.height * cropIncrement / 100);
626
627 // 分配新的内存来存储裁剪后的图像数据
628 uint8_t *croppedData = new uint8_t[newHeight * inputBufferInfo.rowSize];
629
630 // 复制裁剪后的图像数据
631 for (int y = 0; y < newHeight; ++y) {
632 uint8_t *src = static_cast<uint8_t *>(inputBufferInfo.addr) + y * inputBufferInfo.rowSize;
633 uint8_t *dst = croppedData + y * inputBufferInfo.rowSize;
634 for (int x = 0; x < inputBufferInfo.rowSize; ++x) {
635 dst[x] = src[x];
636 }
637 }
638
639 // 设置输出缓冲区的信息
640 outputBufferInfo.addr = croppedData;
641 outputBufferInfo.width = inputBufferInfo.width;
642 outputBufferInfo.height = newHeight;
643 outputBufferInfo.rowSize = inputBufferInfo.rowSize;
644 outputBufferInfo.format = inputBufferInfo.format;
645 }
646
647 // [Start image_effect_render_crop]
RenderCrop(OH_EffectFilter * filter,OH_EffectBufferInfo * info,OH_EffectFilterDelegate_PushData pushData)648 bool RenderCrop(OH_EffectFilter *filter, OH_EffectBufferInfo *info, OH_EffectFilterDelegate_PushData pushData)
649 {
650 // 获取图像信息具体参数。
651 EffectBufferInfo inputBufferInfo;
652 OH_EffectBufferInfo_GetAddr(info, &inputBufferInfo.addr);
653 OH_EffectBufferInfo_GetWidth(info, &inputBufferInfo.width);
654 OH_EffectBufferInfo_GetHeight(info, &inputBufferInfo.height);
655 OH_EffectBufferInfo_GetRowSize(info, &inputBufferInfo.rowSize);
656 OH_EffectBufferInfo_GetEffectFormat(info, &inputBufferInfo.format);
657
658 // 创建输出像素信息。
659 EffectBufferInfo outputBufferInfo;
660
661 // 调用自定义滤镜算法。
662 ApplyCustomCropAlgo(filter, inputBufferInfo, outputBufferInfo);
663
664 // 生成outputOhInfo。
665 OH_EffectBufferInfo *outputOhInfo = OH_EffectBufferInfo_Create();
666 OH_EffectBufferInfo_SetAddr(outputOhInfo, outputBufferInfo.addr);
667 OH_EffectBufferInfo_SetWidth(outputOhInfo, outputBufferInfo.width);
668 OH_EffectBufferInfo_SetHeight(outputOhInfo, outputBufferInfo.height);
669 OH_EffectBufferInfo_SetRowSize(outputOhInfo, outputBufferInfo.rowSize);
670 OH_EffectBufferInfo_SetEffectFormat(outputOhInfo, outputBufferInfo.format);
671
672 // 编辑完成后调用pushData传递outputOhInfo。
673 pushData(filter, outputOhInfo);
674
675 // 释放资源。
676 OH_EffectBufferInfo_Release(outputOhInfo);
677
678 return true;
679 }
680 // [End image_effect_render_crop]
681
SaveFilterBrightness(OH_EffectFilter * filter,char ** info)682 bool SaveFilterBrightness(OH_EffectFilter *filter, char **info)
683 {
684 // 获取自定义所设置的滤镜参数,其中"brightness"为自定义滤镜的Key,由开发者自己任意指定。
685 ImageEffect_Any value;
686 ImageEffect_ErrorCode errorCode = OH_EffectFilter_GetValue(filter, "brightness", &value);
687 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, false,
688 "OH_EffectFilter_GetValue fail! 33 %{public}d", errorCode);
689
690 // 生成键值对信息。
691 Json values;
692 values["brightness"] = value.dataValue.floatValue;
693 Json root;
694 root["name"] = "CustomBrightness";
695 root["values"] = values;
696
697 // 将json对象转成字符串infoStr
698 std::string infoStr = root.Dump();
699
700 // 对*info赋值序列化字符串地址。
701 *info = strdup(infoStr.data());
702
703 return true;
704 }
705
SaveFilterCrop(OH_EffectFilter * filter,char ** info)706 bool SaveFilterCrop(OH_EffectFilter *filter, char **info)
707 {
708 // 获取自定义所设置的滤镜参数,其中"crop"为自定义滤镜的Key,由开发者自己任意指定。
709 ImageEffect_Any value;
710 ImageEffect_ErrorCode errorCode = OH_EffectFilter_GetValue(filter, "crop", &value);
711 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, false,
712 "OH_EffectFilter_GetValue fail! 44 %{public}d", errorCode);
713
714 // 生成键值对信息。
715 Json values;
716 values["crop"] = value.dataValue.floatValue;
717 Json root;
718 root["name"] = "CustomCrop";
719 root["values"] = values;
720
721 // 将json对象转成字符串infoStr
722 std::string infoStr = root.Dump();
723
724 // 对*info赋值序列化字符串地址。
725 *info = strdup(infoStr.data());
726
727 return true;
728 }
729
RegisterCustomBrightness()730 napi_value ImageEdit::RegisterCustomBrightness()
731 {
732 napi_value result = nullptr;
733 // [Start image_effect_create_custom_filter_info]
734 // 创建 OH_EffectFilterInfo 实例。
735 OH_EffectFilterInfo *customFilterInfo = OH_EffectFilterInfo_Create();
736 CHECK_AND_RETURN_RET_LOG(customFilterInfo != nullptr, result, "OH_EffectFilter_GetValue fail!");
737 // 设置自定义滤镜滤镜名。
738 OH_EffectFilterInfo_SetFilterName(customFilterInfo, "CustomBrightness");
739 // 设置自定义滤镜所支持的内存类型。
740 ImageEffect_BufferType bufferTypeArray[] = {ImageEffect_BufferType::EFFECT_BUFFER_TYPE_PIXEL};
741 OH_EffectFilterInfo_SetSupportedBufferTypes(customFilterInfo,
742 sizeof(bufferTypeArray) / sizeof(ImageEffect_BufferType), bufferTypeArray);
743 // 设置自定义滤镜所支持的像素格式。
744 ImageEffect_Format formatArray[] = {ImageEffect_Format::EFFECT_PIXEL_FORMAT_RGBA8888};
745 OH_EffectFilterInfo_SetSupportedFormats(customFilterInfo,
746 sizeof(formatArray) / sizeof(ImageEffect_Format), formatArray);
747 // [End image_effect_create_custom_filter_info]
748 // [Start image_effect_custom_filter]
749 // 自定义滤镜具体实现。
750 delegateBrightness = {
751 .setValue =
752 [](OH_EffectFilter *filter, const char *key, const ImageEffect_Any *value) {
753 // 参数校验,校验成功时返回true,否则返回false。
754 if (value->dataValue.floatValue >= DATA_VALUE_MIN && value->dataValue.floatValue <= DATA_VALUE_MAX) {
755 return true;
756 } else {
757 return false;
758 }
759 },
760 .render = [](OH_EffectFilter *filter, OH_EffectBufferInfo *info,
761 OH_EffectFilterDelegate_PushData pushData) { return RenderBrightness(filter, info, pushData); },
762 .save = SaveFilterBrightness,
763 .restore = [](const char *info) -> OH_EffectFilter * {
764 // 创建 OH_EffectFilter 实例,其中"CustomBrightness"为自定义滤镜的滤镜名。
765 OH_EffectFilter *filter = OH_EffectFilter_Create("CustomBrightness");
766 CHECK_AND_RETURN_RET_LOG(filter != nullptr, nullptr, "OH_EffectFilter_Create fail!");
767 // 解析json字符串info获取key和value。
768 std::map<std::string, std::string> parsedJson = Json::Parse(info);
769 if (parsedJson.find("values") != parsedJson.end()) {
770 std::string valuesStr = parsedJson["values"];
771 std::map<std::string, std::string> valuesJson = Json::Parse(valuesStr);
772 if (valuesJson.find("brightness") != valuesJson.end()) {
773 float brightness =
774 std::stof(valuesJson["brightness"].substr(1, valuesJson["brightness"].size() - 2));
775 ImageEffect_Any value;
776 value.dataType = ImageEffect_DataType::EFFECT_DATA_TYPE_FLOAT;
777 value.dataValue.floatValue = brightness;
778 // 设置滤镜参数, value为info中按json解析出来的参数。
779 LOG_E("brightness value: %{public}f ", value.dataValue.floatValue);
780 ImageEffect_ErrorCode errorCode = OH_EffectFilter_SetValue(filter, "brightness", &value);
781 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, nullptr,
782 "OH_EffectFilter_SetValue fail!");
783 }
784 }
785 return filter;
786 }};
787 // [End image_effect_custom_filter]
788
789 // [Start image_effect_custom_filter_register]
790 ImageEffect_ErrorCode errorCode = OH_EffectFilter_Register(customFilterInfo, &delegateBrightness);
791 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, result,
792 "OH_EffectFilter_Register fail! errorCode = %{public}d", errorCode);
793 // [End image_effect_custom_filter_register]
794 return result;
795 }
796
RegisterCustomCrop()797 napi_value ImageEdit::RegisterCustomCrop()
798 {
799 napi_value result = nullptr;
800 // 创建 OH_EffectFilterInfo 实例。
801 OH_EffectFilterInfo *customFilterInfo = OH_EffectFilterInfo_Create();
802 CHECK_AND_RETURN_RET_LOG(customFilterInfo != nullptr, result, "OH_EffectFilter_GetValue fail!");
803 // 设置自定义滤镜滤镜名。
804 OH_EffectFilterInfo_SetFilterName(customFilterInfo, "CustomCrop");
805 // 设置自定义滤镜所支持的内存类型。
806 ImageEffect_BufferType bufferTypeArray[] = {ImageEffect_BufferType::EFFECT_BUFFER_TYPE_PIXEL};
807 OH_EffectFilterInfo_SetSupportedBufferTypes(customFilterInfo,
808 sizeof(bufferTypeArray) / sizeof(ImageEffect_BufferType), bufferTypeArray);
809 // 设置自定义滤镜所支持的像素格式。
810 ImageEffect_Format formatArray[] = {ImageEffect_Format::EFFECT_PIXEL_FORMAT_RGBA8888};
811 OH_EffectFilterInfo_SetSupportedFormats(customFilterInfo,
812 sizeof(formatArray) / sizeof(ImageEffect_Format), formatArray);
813 // 自定义滤镜具体实现。
814 delegateCrop = {
815 .setValue =
816 [](OH_EffectFilter *filter, const char *key, const ImageEffect_Any *value) {
817 // 参数校验,校验成功时返回true,否则返回false。
818 if (value->dataValue.floatValue >= DATA_VALUE_MIN && value->dataValue.floatValue <= DATA_VALUE_MAX) {
819 return true;
820 } else {
821 return false;
822 }
823 },
824 .render = [](OH_EffectFilter *filter, OH_EffectBufferInfo *info,
825 OH_EffectFilterDelegate_PushData pushData) { return RenderCrop(filter, info, pushData); },
826 .save = SaveFilterCrop,
827 .restore = [](const char *info) -> OH_EffectFilter * {
828 // 创建 OH_EffectFilter 实例,其中"CustomBrightness"为自定义滤镜的滤镜名。
829 OH_EffectFilter *filter = OH_EffectFilter_Create("CustomCrop");
830 CHECK_AND_RETURN_RET_LOG(filter != nullptr, nullptr, "OH_EffectFilter_Create fail!");
831 // 解析json字符串info获取key和value。
832 std::map<std::string, std::string> parsedJson = Json::Parse(info);
833 if (parsedJson.find("values") != parsedJson.end()) {
834 std::string valuesStr = parsedJson["values"];
835 std::map<std::string, std::string> valuesJson = Json::Parse(valuesStr);
836 if (valuesJson.find("crop") != valuesJson.end()) {
837 float crop = std::stof(valuesJson["crop"].substr(1, valuesJson["crop"].size() - 2));
838 ImageEffect_Any value;
839 value.dataType = ImageEffect_DataType::EFFECT_DATA_TYPE_FLOAT;
840 value.dataValue.floatValue = crop;
841 // 设置滤镜参数, value为info中按json解析出来的参数。
842 LOG_E("crop value: %{public}f ", value.dataValue.floatValue);
843 ImageEffect_ErrorCode errorCode = OH_EffectFilter_SetValue(filter, "crop", &value);
844 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, nullptr,
845 "OH_EffectFilter_SetValue fail!");
846 }
847 }
848 return filter;
849 }};
850
851 ImageEffect_ErrorCode errorCode = OH_EffectFilter_Register(customFilterInfo, &delegateCrop);
852 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, result,
853 "OH_EffectFilter_Register fail! errorCode = %{public}d", errorCode);
854 return result;
855 }
856
LookupFilters(napi_env env,napi_callback_info info)857 napi_value ImageEdit::LookupFilters(napi_env env, napi_callback_info info)
858 {
859 napi_value result = nullptr;
860 napi_get_undefined(env, &result);
861 size_t argc = EXPECTED_ARGS_ONE;
862 napi_value args[EXPECTED_ARGS_ONE] = {nullptr};
863 napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
864 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_get_cb_info fail! status = %{public}d", status);
865 const char *key = CommonUtils::GetStringArgument(env, args[EXPECTED_ARGS_ZERO]);
866
867 // [Start image_effect_lookup_filter_info_by_condition]
868 ImageEffect_FilterNames *filterNames = OH_EffectFilter_LookupFilters(key);
869 CHECK_AND_RETURN_RET_LOG(filterNames != nullptr, result, "OH_EffectFilter_LookupFilters fail!");
870
871 std::string res = "size: " + std::to_string(filterNames->size) + std::string(", name: ");
872 for (int i = 0; i < filterNames->size; i++) {
873 res += filterNames->nameList[i];
874 if (i < filterNames->size - 1) {
875 res += " | ";
876 }
877 }
878 status = napi_create_string_utf8(env, res.c_str(), res.size(), &result);
879 // 释放FilterNames虚拟内存资源。
880 OH_EffectFilter_ReleaseFilterNames();
881 // [End image_effect_lookup_filter_info_by_condition]
882 return result;
883 }
884
getSurfaceId(napi_env env,napi_callback_info info)885 napi_value ImageEdit::getSurfaceId(napi_env env, napi_callback_info info)
886 {
887 napi_value result = nullptr;
888 napi_get_undefined(env, &result);
889
890 size_t argc = EXPECTED_ARGS_ONE;
891 napi_value args[EXPECTED_ARGS_ONE] = {nullptr};
892 napi_status status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
893 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_get_cb_info fail! status = %{public}d", status);
894
895 std::string surfaceId = CommonUtils::GetStringArgument(env, args[EXPECTED_ARGS_ZERO]);
896 // [Start image_effect_get_surface_id]
897 // 根据SurfaceId创建NativeWindow,注意创建出来的NativeWindow在使用结束后需要主动调用OH_NativeWindow_DestoryNativeWindow进行释放。
898 uint64_t outputSurfaceId;
899 std::istrstream iss(surfaceId.c_str());
900 iss >> outputSurfaceId;
901 LOG_I("outputSurfaceId %{public}llu", outputSurfaceId);
902 OHNativeWindow *outputNativeWindow = nullptr;
903 int32_t res = OH_NativeWindow_CreateNativeWindowFromSurfaceId(outputSurfaceId, &outputNativeWindow);
904 CHECK_AND_RETURN_RET_LOG(res == 0, result, "OH_NativeWindow_CreateNativeWindowFromSurfaceId fail!");
905
906 OH_ImageEffect *imageEffect = OH_ImageEffect_Create("imageEdit");
907 CHECK_AND_RETURN_RET_LOG(imageEffect != nullptr, result, "OH_ImageEffect_Create fail!");
908
909 ImageEffect_Any runningType;
910 runningType.dataType = ImageEffect_DataType::EFFECT_DATA_TYPE_INT32;
911 runningType.dataValue.int32Value = 1;
912 ImageEffect_ErrorCode errorCode = OH_ImageEffect_Configure(imageEffect, "runningType", &runningType);
913 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, result,
914 "OH_ImageEffect_Configure fail!");
915
916 // 设置输出显示的Surface。
917 errorCode = OH_ImageEffect_SetOutputSurface(imageEffect, outputNativeWindow);
918 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, result,
919 "OH_ImageEffect_SetOutputSurface fail!");
920
921 // 获取输入的Surface。注意获取的inputNativeWindow在使用结束后需要主动调用OH_NativeWindow_DestoryNativeWindow进行释放。
922 OHNativeWindow *inputNativeWindow = nullptr;
923 errorCode = OH_ImageEffect_GetInputSurface(imageEffect, &inputNativeWindow);
924 CHECK_AND_RETURN_RET_LOG(errorCode == ImageEffect_ErrorCode::EFFECT_SUCCESS, result,
925 "OH_ImageEffect_GetInputSurface fail!");
926
927 ImageEdit::imageEffect_ = imageEffect;
928
929 // 从获取到输入的NativeWindow中获取SurfaceId。
930 uint64_t inputSurfaceId = 0;
931 res = OH_NativeWindow_GetSurfaceId(inputNativeWindow, &inputSurfaceId);
932 CHECK_AND_RETURN_RET_LOG(res == 0, result, "OH_NativeWindow_GetSurfaceId fail!");
933
934 OH_NativeWindow_DestroyNativeWindow(outputNativeWindow);
935 OH_NativeWindow_DestroyNativeWindow(inputNativeWindow);
936
937 std::string inputSurfaceIdStr = std::to_string(inputSurfaceId);
938 // [End image_effect_get_surface_id]
939
940 status = napi_create_string_utf8(env, inputSurfaceIdStr.c_str(), inputSurfaceIdStr.length(), &result);
941 CHECK_AND_RETURN_RET_LOG(status == napi_status::napi_ok, result, "napi_create_string_utf8 fail!");
942 return result;
943 }
944