• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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