• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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 "bridge/declarative_frontend/jsview/js_image.h"
17 
18 #include <cstdint>
19 #include <memory>
20 #include <vector>
21 #if !defined(PREVIEW)
22 #include <dlfcn.h>
23 #endif
24 
25 #include "interfaces/inner_api/ace/ai/image_analyzer.h"
26 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
27 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
28 #endif
29 
30 #include "base/geometry/ng/vector.h"
31 #include "base/image/drawing_color_filter.h"
32 #include "base/image/drawing_lattice.h"
33 #include "base/image/pixel_map.h"
34 #include "base/log/ace_scoring_log.h"
35 #include "base/log/ace_trace.h"
36 #include "base/utils/utils.h"
37 #include "bridge/common/utils/engine_helper.h"
38 #include "bridge/declarative_frontend/engine/functions/js_drag_function.h"
39 #include "bridge/declarative_frontend/engine/js_ref_ptr.h"
40 #include "bridge/declarative_frontend/engine/js_types.h"
41 #include "bridge/declarative_frontend/engine/jsi/js_ui_index.h"
42 #include "bridge/declarative_frontend/jsview/models/image_model_impl.h"
43 #include "core/common/container.h"
44 #include "core/components/common/layout/constants.h"
45 #include "core/components/image/image_event.h"
46 #include "core/components/image/image_theme.h"
47 #include "core/components_ng/base/view_abstract_model.h"
48 #include "core/components_ng/base/view_stack_processor.h"
49 #include "core/components_ng/event/gesture_event_hub.h"
50 #include "core/components_ng/pattern/image/image_model.h"
51 #include "core/components_ng/pattern/image/image_model_ng.h"
52 #include "core/image/image_source_info.h"
53 
54 namespace {
55 const std::vector<float> DEFAULT_COLORFILTER_MATRIX = { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0 };
56 constexpr float CEIL_SMOOTHEDGE_VALUE = 1.333f;
57 constexpr float FLOOR_SMOOTHEDGE_VALUE = 0.334f;
58 constexpr float DEFAULT_SMOOTHEDGE_VALUE = 0.0f;
59 constexpr uint32_t FIT_MATRIX = 16;
60 } // namespace
61 
62 namespace OHOS::Ace {
63 
64 namespace {
CreateSourceInfo(const std::shared_ptr<std::string> & srcRef,RefPtr<PixelMap> & pixmap,const std::string & bundleName,const std::string & moduleName)65 ImageSourceInfo CreateSourceInfo(const std::shared_ptr<std::string>& srcRef, RefPtr<PixelMap>& pixmap,
66     const std::string& bundleName, const std::string& moduleName)
67 {
68 #if defined(PIXEL_MAP_SUPPORTED)
69     if (pixmap) {
70         return ImageSourceInfo(pixmap);
71     }
72 #endif
73     return { srcRef, bundleName, moduleName };
74 }
75 } // namespace
76 
77 std::unique_ptr<ImageModel> ImageModel::instance_ = nullptr;
78 std::mutex ImageModel::mutex_;
79 
GetInstance()80 ImageModel* __attribute__((optnone)) ImageModel::GetInstance()
81 {
82     if (!instance_) {
83         std::lock_guard<std::mutex> lock(mutex_);
84         if (!instance_) {
85 #ifdef NG_BUILD
86             instance_.reset(new NG::ImageModelNG());
87 #else
88             if (Container::IsCurrentUseNewPipeline()) {
89                 instance_.reset(new NG::ImageModelNG());
90             } else {
91                 instance_.reset(new Framework::ImageModelImpl());
92             }
93 #endif
94         }
95     }
96     return instance_.get();
97 }
98 
99 } // namespace OHOS::Ace
100 
101 namespace OHOS::Ace::Framework {
102 
LoadImageSuccEventToJSValue(const LoadImageSuccessEvent & eventInfo)103 JSRef<JSVal> LoadImageSuccEventToJSValue(const LoadImageSuccessEvent& eventInfo)
104 {
105     JSRef<JSObject> obj = JSRef<JSObject>::New();
106     obj->SetProperty("width", eventInfo.GetWidth());
107     obj->SetProperty("height", eventInfo.GetHeight());
108     obj->SetProperty("componentWidth", eventInfo.GetComponentWidth());
109     obj->SetProperty("componentHeight", eventInfo.GetComponentHeight());
110     obj->SetProperty("loadingStatus", eventInfo.GetLoadingStatus());
111     obj->SetProperty("contentWidth", eventInfo.GetContentWidth());
112     obj->SetProperty("contentHeight", eventInfo.GetContentHeight());
113     obj->SetProperty("contentOffsetX", eventInfo.GetContentOffsetX());
114     obj->SetProperty("contentOffsetY", eventInfo.GetContentOffsetY());
115     return JSRef<JSVal>::Cast(obj);
116 }
117 
LoadImageFailEventToJSValue(const LoadImageFailEvent & eventInfo)118 JSRef<JSVal> LoadImageFailEventToJSValue(const LoadImageFailEvent& eventInfo)
119 {
120     JSRef<JSObject> obj = JSRef<JSObject>::New();
121     obj->SetProperty("componentWidth", eventInfo.GetComponentWidth());
122     obj->SetProperty("componentHeight", eventInfo.GetComponentHeight());
123     obj->SetProperty("message", eventInfo.GetErrorMessage());
124     return JSRef<JSVal>::Cast(obj);
125 }
126 
SetAlt(const JSCallbackInfo & args)127 void JSImage::SetAlt(const JSCallbackInfo& args)
128 {
129     if (ImageModel::GetInstance()->GetIsAnimation()) {
130         return;
131     }
132     if (args.Length() < 1) {
133         return;
134     }
135 
136     auto context = PipelineBase::GetCurrentContext();
137     CHECK_NULL_VOID(context);
138     bool isCard = context->IsFormRender();
139 
140     std::string src;
141     bool srcValid = false;
142     if (args[0]->IsString()) {
143         src = args[0]->ToString();
144     } else {
145         srcValid = ParseJsMedia(args[0], src);
146     }
147     if (ImageSourceInfo::ResolveURIType(src) == SrcType::NETWORK) {
148         return;
149     }
150     int32_t resId = 0;
151     if (args[0]->IsObject()) {
152         JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(args[0]);
153         JSRef<JSVal> tmp = jsObj->GetProperty("id");
154         if (!tmp->IsNull() && tmp->IsNumber()) {
155             resId = tmp->ToNumber<int32_t>();
156         }
157     }
158     std::string bundleName;
159     std::string moduleName;
160     GetJsMediaBundleInfo(args[0], bundleName, moduleName);
161     RefPtr<PixelMap> pixmap = nullptr;
162 
163     // input is Drawable
164     if (!srcValid && !isCard) {
165 #if defined(PIXEL_MAP_SUPPORTED)
166         pixmap = CreatePixelMapFromNapiValue(args[0]);
167 #endif
168     }
169     auto srcRef = std::make_shared<std::string>(src);
170     auto srcInfo = CreateSourceInfo(srcRef, pixmap, bundleName, moduleName);
171     srcInfo.SetIsUriPureNumber((resId == -1));
172     ImageModel::GetInstance()->SetAlt(srcInfo);
173 }
174 
SetObjectFit(const JSCallbackInfo & args)175 void JSImage::SetObjectFit(const JSCallbackInfo& args)
176 {
177     if (args.Length() < 1) {
178         ImageModel::GetInstance()->SetImageFit(ImageFit::COVER);
179         return;
180     }
181     int32_t parseRes = static_cast<int32_t>(ImageFit::COVER);
182     ParseJsInteger(args[0], parseRes);
183     if (parseRes < static_cast<int32_t>(ImageFit::FILL) || parseRes > static_cast<int32_t>(ImageFit::MATRIX)) {
184         parseRes = static_cast<int32_t>(ImageFit::COVER);
185     }
186     auto fit = static_cast<ImageFit>(parseRes);
187     if (parseRes == FIT_MATRIX) {
188         fit = ImageFit::MATRIX;
189     }
190     ImageModel::GetInstance()->SetImageFit(fit);
191 }
192 
SetImageMatrix(const JSCallbackInfo & args)193 void JSImage::SetImageMatrix(const JSCallbackInfo& args)
194 {
195     if (args.Length() > 0) {
196         auto jsVal = args[0];
197         if (!jsVal->IsObject()) {
198             SetDefaultImageMatrix();
199             return;
200         }
201         JSRef<JSVal> array = JSRef<JSObject>::Cast(jsVal)->GetProperty(static_cast<int32_t>(ArkUIIndex::MATRIX4X4));
202         const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
203         if (!array->IsArray()) {
204             return;
205         }
206         JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(array);
207         if (jsArray->Length() != matrix4Len) {
208             return;
209         }
210         std::vector<float> matrix(matrix4Len);
211         for (int32_t i = 0; i < matrix4Len; i++) {
212             double value = 0.0;
213             ParseJsDouble(jsArray->GetValueAt(i), value);
214             matrix[i] = static_cast<float>(value);
215         }
216         Matrix4 setValue = Matrix4(
217             matrix[0], matrix[4], matrix[8], matrix[12],
218             matrix[1], matrix[5], matrix[9], matrix[13],
219             matrix[2], matrix[6], matrix[10], matrix[14],
220             matrix[3], matrix[7], matrix[11], matrix[15]);
221         ImageModel::GetInstance()->SetImageMatrix(setValue);
222     } else {
223         SetDefaultImageMatrix();
224         return;
225     }
226 }
227 
SetDefaultImageMatrix()228 void JSImage::SetDefaultImageMatrix()
229 {
230     const auto matrix4Len = Matrix4::DIMENSION * Matrix4::DIMENSION;
231     std::vector<float> matrix(matrix4Len);
232     const int32_t initPosition = 5;
233     for (int32_t i = 0; i < matrix4Len; i = i + initPosition) {
234         matrix[i] = 1.0f;
235     }
236     Matrix4 setValue = Matrix4(
237         matrix[0], matrix[4], matrix[8], matrix[12],
238         matrix[1], matrix[5], matrix[9], matrix[13],
239         matrix[2], matrix[6], matrix[10], matrix[14],
240         matrix[3], matrix[7], matrix[11], matrix[15]);
241     ImageModel::GetInstance()->SetImageMatrix(setValue);
242 }
243 
SetMatchTextDirection(bool value)244 void JSImage::SetMatchTextDirection(bool value)
245 {
246     if (ImageModel::GetInstance()->GetIsAnimation()) {
247         return;
248     }
249     ImageModel::GetInstance()->SetMatchTextDirection(value);
250 }
251 
SetFitOriginalSize(bool value)252 void JSImage::SetFitOriginalSize(bool value)
253 {
254     if (ImageModel::GetInstance()->GetIsAnimation()) {
255         return;
256     }
257     ImageModel::GetInstance()->SetFitOriginSize(value);
258 }
259 
SetBorder(const Border & border)260 void JSImage::SetBorder(const Border& border)
261 {
262     ImageModel::GetInstance()->SetBorder(border);
263 }
264 
OnComplete(const JSCallbackInfo & args)265 void JSImage::OnComplete(const JSCallbackInfo& args)
266 {
267     if (args[0]->IsFunction()) {
268         auto jsLoadSuccFunc = AceType::MakeRefPtr<JsEventFunction<LoadImageSuccessEvent, 1>>(
269             JSRef<JSFunc>::Cast(args[0]), LoadImageSuccEventToJSValue);
270 
271         auto onComplete = [execCtx = args.GetExecutionContext(), func = std::move(jsLoadSuccFunc)](
272                               const LoadImageSuccessEvent& info) {
273             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
274             ACE_SCORING_EVENT("Image.onComplete");
275             func->Execute(info);
276 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
277             UiSessionManager::GetInstance().ReportComponentChangeEvent("event", "Image.onComplete");
278 #endif
279         };
280         ImageModel::GetInstance()->SetOnComplete(std::move(onComplete));
281     }
282 }
283 
OnError(const JSCallbackInfo & args)284 void JSImage::OnError(const JSCallbackInfo& args)
285 {
286     if (args[0]->IsFunction()) {
287         auto jsLoadFailFunc = AceType::MakeRefPtr<JsEventFunction<LoadImageFailEvent, 1>>(
288             JSRef<JSFunc>::Cast(args[0]), LoadImageFailEventToJSValue);
289         auto onError = [execCtx = args.GetExecutionContext(), func = std::move(jsLoadFailFunc)](
290                            const LoadImageFailEvent& info) {
291             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
292             ACE_SCORING_EVENT("Image.onError");
293             func->Execute(info);
294 #if !defined(PREVIEW) && defined(OHOS_PLATFORM)
295             UiSessionManager::GetInstance().ReportComponentChangeEvent("event", "Image.onError");
296 #endif
297         };
298 
299         ImageModel::GetInstance()->SetOnError(onError);
300     }
301 }
302 
OnFinish(const JSCallbackInfo & info)303 void JSImage::OnFinish(const JSCallbackInfo& info)
304 {
305     auto tmpInfo = info[0];
306     if (!tmpInfo->IsFunction()) {
307         return;
308     }
309     RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(tmpInfo));
310     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
311     auto onFinish = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
312         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
313         ACE_SCORING_EVENT("Image.onFinish");
314         PipelineContext::SetCallBackNode(node);
315         func->Execute();
316     };
317     ImageModel::GetInstance()->SetSvgAnimatorFinishEvent(onFinish);
318 }
319 
Create(const JSCallbackInfo & info)320 void JSImage::Create(const JSCallbackInfo& info)
321 {
322     if (info.Length() < 1) {
323         return;
324     }
325     CreateImage(info);
326 }
327 
CheckIsCard()328 bool JSImage::CheckIsCard()
329 {
330     auto container = Container::Current();
331     if (!container) {
332         TAG_LOGE(AceLogTag::ACE_IMAGE, "Container is null in CreateImage.");
333         return false;
334     }
335     return container->IsFormRender() && !container->IsDynamicRender();
336 }
337 
CheckResetImage(const JSCallbackInfo & info)338 bool JSImage::CheckResetImage(const JSCallbackInfo& info)
339 {
340     int32_t parseRes = -1;
341     if (info.Length() < 1 || !ParseJsInteger(info[0], parseRes)) {
342         return false;
343     }
344     ImageModel::GetInstance()->ResetImage();
345     return true;
346 }
347 
CreateImage(const JSCallbackInfo & info,bool isImageSpan)348 void JSImage::CreateImage(const JSCallbackInfo& info, bool isImageSpan)
349 {
350     if (CheckResetImage(info)) {
351         return;
352     }
353     bool isCard = CheckIsCard();
354 
355     // Interim programme
356     std::string bundleName;
357     std::string moduleName;
358     std::string src;
359     auto imageInfo = info[0];
360     int32_t resId = 0;
361     bool srcValid = ParseJsMediaWithBundleName(imageInfo, src, bundleName, moduleName, resId);
362     if (isCard && imageInfo->IsString()) {
363         SrcType srcType = ImageSourceInfo::ResolveURIType(src);
364         bool notSupport = (srcType == SrcType::NETWORK || srcType == SrcType::FILE || srcType == SrcType::DATA_ABILITY);
365         if (notSupport) {
366             src.clear();
367         }
368     }
369     RefPtr<PixelMap> pixmap = nullptr;
370 
371     // input is PixelMap / Drawable
372     if (!srcValid && !isCard) {
373 #if defined(PIXEL_MAP_SUPPORTED)
374         std::vector<RefPtr<PixelMap>> pixelMaps;
375         int32_t duration = -1;
376         int32_t iterations = 1;
377         if (IsDrawable(imageInfo)) {
378             if (GetPixelMapListFromAnimatedDrawable(imageInfo, pixelMaps, duration, iterations)) {
379                 CreateImageAnimation(pixelMaps, duration, iterations);
380                 return;
381             }
382             pixmap = GetDrawablePixmap(imageInfo);
383         } else {
384             pixmap = CreatePixelMapFromNapiValue(imageInfo);
385         }
386 #endif
387     }
388     ImageInfoConfig imageInfoConfig(
389         std::make_shared<std::string>(src), bundleName, moduleName, (resId == -1), isImageSpan);
390     ImageModel::GetInstance()->Create(imageInfoConfig, pixmap);
391 
392     if (info.Length() > 1) {
393         ParseImageAIOptions(info[1]);
394     }
395 }
396 
ParseImageAIOptions(const JSRef<JSVal> & jsValue)397 void JSImage::ParseImageAIOptions(const JSRef<JSVal>& jsValue)
398 {
399     if (!jsValue->IsObject()) {
400         return;
401     }
402     auto engine = EngineHelper::GetCurrentEngine();
403     CHECK_NULL_VOID(engine);
404     NativeEngine* nativeEngine = engine->GetNativeEngine();
405     panda::Local<JsiValue> value = jsValue.Get().GetLocalHandle();
406     JSValueWrapper valueWrapper = value;
407     ScopeRAII scope(reinterpret_cast<napi_env>(nativeEngine));
408     napi_value optionsValue = nativeEngine->ValueToNapiValue(valueWrapper);
409     ImageModel::GetInstance()->SetImageAIOptions(optionsValue);
410 }
411 
IsDrawable(const JSRef<JSVal> & jsValue)412 bool JSImage::IsDrawable(const JSRef<JSVal>& jsValue)
413 {
414     if (!jsValue->IsObject()) {
415         return false;
416     }
417     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(jsValue);
418     if (jsObj->IsUndefined()) {
419         return false;
420     }
421 
422     // if jsObject has function getPixelMap, it's a DrawableDescriptor object
423     JSRef<JSVal> func = jsObj->GetProperty("getPixelMap");
424     return (!func->IsNull() && func->IsFunction());
425 }
426 
JsBorder(const JSCallbackInfo & info)427 void JSImage::JsBorder(const JSCallbackInfo& info)
428 {
429     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_FOURTEEN)) {
430         JSViewAbstract::JsBorder(info);
431         ImageModel::GetInstance()->SetBackBorder();
432         return;
433     }
434     // handles generic property logic.
435     JSViewAbstract::JsBorder(info);
436     // handles the image component separately, aiming to extract and set the borderRadius property
437     if (!info[0]->IsObject()) {
438         CalcDimension borderRadius;
439         ImageModel::GetInstance()->SetBorderRadius(borderRadius);
440         return;
441     }
442     JSRef<JSObject> object = JSRef<JSObject>::Cast(info[0]);
443 
444     auto valueRadius = object->GetProperty(static_cast<int32_t>(ArkUIIndex::RADIUS));
445     if (!valueRadius->IsUndefined()) {
446         ParseBorderRadius(valueRadius);
447     }
448 }
449 
ParseBorderRadius(const JSRef<JSVal> & args)450 void JSImage::ParseBorderRadius(const JSRef<JSVal>& args)
451 {
452     CalcDimension borderRadius;
453     if (ParseJsDimensionVp(args, borderRadius)) {
454         ViewAbstractModel::GetInstance()->SetBorderRadius(borderRadius);
455         ImageModel::GetInstance()->SetBorderRadius(borderRadius);
456     } else if (args->IsObject()) {
457         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
458         CalcDimension topLeft;
459         CalcDimension topRight;
460         CalcDimension bottomLeft;
461         CalcDimension bottomRight;
462         if (ParseAllBorderRadiuses(object, topLeft, topRight, bottomLeft, bottomRight)) {
463             ImageModel::GetInstance()->SetBorderRadius(
464                 GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
465             ViewAbstractModel::GetInstance()->SetBorderRadius(
466                 GetLocalizedBorderRadius(topLeft, topRight, bottomLeft, bottomRight));
467             return;
468         }
469         ImageModel::GetInstance()->SetBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
470         ViewAbstractModel::GetInstance()->SetBorderRadius(topLeft, topRight, bottomLeft, bottomRight);
471     }
472 }
473 
ParseResizableSlice(const JSRef<JSObject> & resizableObject)474 void JSImage::ParseResizableSlice(const JSRef<JSObject>& resizableObject)
475 {
476     ImageResizableSlice sliceResult;
477     if (resizableObject->IsEmpty()) {
478         ImageModel::GetInstance()->SetResizableSlice(sliceResult);
479         return;
480     }
481     auto sliceValue = resizableObject->GetProperty("slice");
482     if (!sliceValue->IsObject()) {
483         ImageModel::GetInstance()->SetResizableSlice(sliceResult);
484         return;
485     }
486     JSRef<JSObject> sliceObj = JSRef<JSObject>::Cast(sliceValue);
487     if (sliceObj->IsEmpty()) {
488         ImageModel::GetInstance()->SetResizableSlice(sliceResult);
489         return;
490     }
491     UpdateSliceResult(sliceObj, sliceResult);
492 
493     ImageModel::GetInstance()->SetResizableSlice(sliceResult);
494 }
495 
ParseResizableLattice(const JSRef<JSObject> & resizableObject)496 void JSImage::ParseResizableLattice(const JSRef<JSObject>& resizableObject)
497 {
498     auto latticeValue = resizableObject->GetProperty("lattice");
499     if (latticeValue->IsUndefined() || latticeValue->IsNull()) {
500         ImageModel::GetInstance()->ResetResizableLattice();
501     }
502     CHECK_NULL_VOID(latticeValue->IsObject());
503     auto drawingLattice = CreateDrawingLattice(latticeValue);
504     if (drawingLattice) {
505         ImageModel::GetInstance()->SetResizableLattice(drawingLattice);
506     } else {
507         ImageModel::GetInstance()->ResetResizableLattice();
508     }
509 }
510 
JsImageResizable(const JSCallbackInfo & info)511 void JSImage::JsImageResizable(const JSCallbackInfo& info)
512 {
513     if (ImageModel::GetInstance()->GetIsAnimation()) {
514         return;
515     }
516     auto infoObj = info[0];
517     if (!infoObj->IsObject()) {
518         ImageModel::GetInstance()->SetResizableSlice(ImageResizableSlice());
519         return;
520     }
521     JSRef<JSObject> resizableObject = JSRef<JSObject>::Cast(infoObj);
522     ParseResizableSlice(resizableObject);
523     ParseResizableLattice(resizableObject);
524 }
525 
UpdateSliceResult(const JSRef<JSObject> & sliceObj,ImageResizableSlice & sliceResult)526 void JSImage::UpdateSliceResult(const JSRef<JSObject>& sliceObj, ImageResizableSlice& sliceResult)
527 {
528     // creatge a array has 4 elements for paresing sliceSize
529     static std::array<int32_t, 4> keys = { static_cast<int32_t>(ArkUIIndex::LEFT),
530         static_cast<int32_t>(ArkUIIndex::RIGHT), static_cast<int32_t>(ArkUIIndex::TOP),
531         static_cast<int32_t>(ArkUIIndex::BOTTOM) };
532     for (uint32_t i = 0; i < keys.size(); i++) {
533         auto sliceSize = sliceObj->GetProperty(keys.at(i));
534         CalcDimension sliceDimension;
535         if (!ParseJsDimensionVp(sliceSize, sliceDimension)) {
536             continue;
537         }
538         if (!sliceDimension.IsValid()) {
539             continue;
540         }
541         switch (static_cast<BorderImageDirection>(i)) {
542             case BorderImageDirection::LEFT:
543                 sliceResult.left = sliceDimension;
544                 break;
545             case BorderImageDirection::RIGHT:
546                 sliceResult.right = sliceDimension;
547                 break;
548             case BorderImageDirection::TOP:
549                 sliceResult.top = sliceDimension;
550                 break;
551             case BorderImageDirection::BOTTOM:
552                 sliceResult.bottom = sliceDimension;
553                 break;
554             default:
555                 break;
556         }
557     }
558     ImageModel::GetInstance()->SetResizableSlice(sliceResult);
559 }
560 
JsBorderRadius(const JSCallbackInfo & info)561 void JSImage::JsBorderRadius(const JSCallbackInfo& info)
562 {
563     if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_FOURTEEN)) {
564         JSViewAbstract::JsBorderRadius(info);
565         ImageModel::GetInstance()->SetBackBorder();
566         return;
567     }
568     static std::vector<JSCallbackInfoType> checkList { JSCallbackInfoType::STRING, JSCallbackInfoType::NUMBER,
569         JSCallbackInfoType::OBJECT };
570     auto jsVal = info[0];
571     if (!CheckJSCallbackInfo("JsBorderRadius", jsVal, checkList)) {
572         ViewAbstractModel::GetInstance()->SetBorderRadius(Dimension {});
573         ImageModel::GetInstance()->SetBorderRadius(Dimension {});
574         return;
575     }
576     ParseBorderRadius(jsVal);
577 }
578 
SetSourceSize(const JSCallbackInfo & info)579 void JSImage::SetSourceSize(const JSCallbackInfo& info)
580 {
581     if (ImageModel::GetInstance()->GetIsAnimation()) {
582         return;
583     }
584     ImageModel::GetInstance()->SetImageSourceSize(JSViewAbstract::ParseSize(info));
585 }
586 
ParseColorContent(const JSRef<JSVal> & jsValue)587 bool JSImage::ParseColorContent(const JSRef<JSVal>& jsValue)
588 {
589     if (jsValue.IsEmpty() || jsValue->IsNull() || !jsValue->IsObject()) {
590         return false;
591     }
592     auto paramObject = JSRef<JSObject>::Cast(jsValue);
593     JSRef<JSVal> typeVal = paramObject->GetProperty("colorContent_");
594     return !typeVal.IsEmpty() && typeVal->IsString() && typeVal->ToString() == "ORIGIN";
595 }
596 
SetImageFill(const JSCallbackInfo & info)597 void JSImage::SetImageFill(const JSCallbackInfo& info)
598 {
599     if (ImageModel::GetInstance()->GetIsAnimation()) {
600         return;
601     }
602     if (info.Length() < 1) {
603         return;
604     }
605 
606     Color color;
607     if (!ParseJsColor(info[0], color)) {
608         if (ParseColorContent(info[0])) {
609             ImageModel::GetInstance()->ResetImageFill();
610             return;
611         }
612         if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
613             return;
614         }
615         auto pipelineContext = PipelineBase::GetCurrentContext();
616         CHECK_NULL_VOID(pipelineContext);
617         auto theme = pipelineContext->GetTheme<ImageTheme>();
618         CHECK_NULL_VOID(theme);
619         color = theme->GetFillColor();
620     }
621     ImageModel::GetInstance()->SetImageFill(color);
622 }
623 
SetImageRenderMode(const JSCallbackInfo & info)624 void JSImage::SetImageRenderMode(const JSCallbackInfo& info)
625 {
626     if (ImageModel::GetInstance()->GetIsAnimation()) {
627         return;
628     }
629     if (info.Length() < 1) {
630         ImageModel::GetInstance()->SetImageRenderMode(ImageRenderMode::ORIGINAL);
631         return;
632     }
633     auto jsImageRenderMode = info[0];
634     if (jsImageRenderMode->IsNumber()) {
635         auto renderMode = static_cast<ImageRenderMode>(jsImageRenderMode->ToNumber<int32_t>());
636         if (renderMode < ImageRenderMode::ORIGINAL || renderMode > ImageRenderMode::TEMPLATE) {
637             renderMode = ImageRenderMode::ORIGINAL;
638         }
639         ImageModel::GetInstance()->SetImageRenderMode(renderMode);
640     } else {
641         ImageModel::GetInstance()->SetImageRenderMode(ImageRenderMode::ORIGINAL);
642     }
643 }
644 
SetImageInterpolation(int32_t imageInterpolation)645 void JSImage::SetImageInterpolation(int32_t imageInterpolation)
646 {
647     if (ImageModel::GetInstance()->GetIsAnimation()) {
648         return;
649     }
650     auto interpolation = static_cast<ImageInterpolation>(imageInterpolation);
651     if (interpolation < ImageInterpolation::NONE || interpolation > ImageInterpolation::HIGH) {
652         interpolation = ImageInterpolation::NONE;
653     }
654     ImageModel::GetInstance()->SetImageInterpolation(interpolation);
655 }
656 
SetImageRepeat(int32_t imageRepeat)657 void JSImage::SetImageRepeat(int32_t imageRepeat)
658 {
659     auto repeat = static_cast<ImageRepeat>(imageRepeat);
660     if (repeat < ImageRepeat::NO_REPEAT || repeat > ImageRepeat::REPEAT) {
661         repeat = ImageRepeat::NO_REPEAT;
662     }
663     ImageModel::GetInstance()->SetImageRepeat(repeat);
664 }
665 
JsTransition(const JSCallbackInfo & info)666 void JSImage::JsTransition(const JSCallbackInfo& info)
667 {
668     if (ImageModel::GetInstance()->IsSrcSvgImage()) {
669         JSViewAbstract::JsTransition(info);
670     } else {
671         JSViewAbstract::JsTransitionPassThrough(info);
672     }
673 }
674 
JsOpacity(const JSCallbackInfo & info)675 void JSImage::JsOpacity(const JSCallbackInfo& info)
676 {
677     if (ImageModel::GetInstance()->IsSrcSvgImage()) {
678         JSViewAbstract::JsOpacity(info);
679     } else {
680         JSViewAbstract::JsOpacityPassThrough(info);
681     }
682 }
683 
JsBlur(const JSCallbackInfo & info)684 void JSImage::JsBlur(const JSCallbackInfo& info)
685 {
686 // only flutter runs special image blur
687 #ifdef ENABLE_ROSEN_BACKEND
688     JSViewAbstract::JsBlur(info);
689 #else
690     if (info.Length() < 1) {
691         return;
692     }
693     double blur = 0.0;
694     if (ParseJsDouble(info[0], blur)) {
695         ImageModel::GetInstance()->SetBlur(blur);
696     }
697 #endif
698 }
699 
SetAutoResize(bool autoResize)700 void JSImage::SetAutoResize(bool autoResize)
701 {
702     if (ImageModel::GetInstance()->GetIsAnimation()) {
703         return;
704     }
705     ImageModel::GetInstance()->SetAutoResize(autoResize);
706 }
707 
SetSyncLoad(const JSCallbackInfo & info)708 void JSImage::SetSyncLoad(const JSCallbackInfo& info)
709 {
710     if (ImageModel::GetInstance()->GetIsAnimation()) {
711         return;
712     }
713     if (info.Length() < 1) {
714         return;
715     }
716     auto tmpInfo = info[0];
717     if (!tmpInfo->IsBoolean()) {
718         return;
719     }
720     ImageModel::GetInstance()->SetSyncMode(tmpInfo->ToBoolean());
721 }
722 
ConstructorCallback(const JSCallbackInfo & args)723 void JSColorFilter::ConstructorCallback(const JSCallbackInfo& args)
724 {
725     if (args.Length() < 1) {
726         return;
727     }
728     auto tmpInfo = args[0];
729     if (!tmpInfo->IsArray()) {
730         return;
731     }
732     JSRef<JSArray> array = JSRef<JSArray>::Cast(tmpInfo);
733     if (array->Length() != COLOR_FILTER_MATRIX_SIZE) {
734         return;
735     }
736     auto jscolorfilter = Referenced::MakeRefPtr<JSColorFilter>();
737     if (jscolorfilter == nullptr) {
738         return;
739     }
740     std::vector<float> colorfilter;
741     for (size_t i = 0; i < array->Length(); i++) {
742         JSRef<JSVal> value = array->GetValueAt(i);
743         if (value->IsNumber()) {
744             colorfilter.emplace_back(value->ToNumber<float>());
745         }
746     }
747     if (colorfilter.size() != COLOR_FILTER_MATRIX_SIZE) {
748         return;
749     }
750     jscolorfilter->SetColorFilterMatrix(std::move(colorfilter));
751     jscolorfilter->IncRefCount();
752     args.SetReturnValue(Referenced::RawPtr(jscolorfilter));
753 }
754 
DestructorCallback(JSColorFilter * obj)755 void JSColorFilter::DestructorCallback(JSColorFilter* obj)
756 {
757     if (obj != nullptr) {
758         obj->DecRefCount();
759     }
760 }
761 
SetColorFilter(const JSCallbackInfo & info)762 void JSImage::SetColorFilter(const JSCallbackInfo& info)
763 {
764     if (info.Length() != 1) {
765         ImageModel::GetInstance()->SetColorFilterMatrix(DEFAULT_COLORFILTER_MATRIX);
766         return;
767     }
768     auto tmpInfo = info[0];
769     if (!tmpInfo->IsArray() && !tmpInfo->IsObject()) {
770         ImageModel::GetInstance()->SetColorFilterMatrix(DEFAULT_COLORFILTER_MATRIX);
771         return;
772     }
773     if (tmpInfo->IsObject() && !tmpInfo->IsArray()) {
774         auto drawingColorFilter = CreateDrawingColorFilter(tmpInfo);
775         if (drawingColorFilter) {
776             ImageModel::GetInstance()->SetDrawingColorFilter(drawingColorFilter);
777             return;
778         }
779         JSColorFilter* colorFilter;
780         if (!tmpInfo->IsUndefined() && !tmpInfo->IsNull()) {
781             colorFilter = JSRef<JSObject>::Cast(tmpInfo)->Unwrap<JSColorFilter>();
782         } else {
783             ImageModel::GetInstance()->SetColorFilterMatrix(DEFAULT_COLORFILTER_MATRIX);
784             return;
785         }
786         if (colorFilter && colorFilter->GetColorFilterMatrix().size() == COLOR_FILTER_MATRIX_SIZE) {
787             ImageModel::GetInstance()->SetColorFilterMatrix(colorFilter->GetColorFilterMatrix());
788             return;
789         }
790         ImageModel::GetInstance()->SetColorFilterMatrix(DEFAULT_COLORFILTER_MATRIX);
791         return;
792     }
793     JSRef<JSArray> array = JSRef<JSArray>::Cast(tmpInfo);
794     if (array->Length() != COLOR_FILTER_MATRIX_SIZE) {
795         ImageModel::GetInstance()->SetColorFilterMatrix(DEFAULT_COLORFILTER_MATRIX);
796         return;
797     }
798     std::vector<float> colorfilter;
799     for (size_t i = 0; i < array->Length(); i++) {
800         JSRef<JSVal> value = array->GetValueAt(i);
801         if (value->IsNumber()) {
802             colorfilter.emplace_back(value->ToNumber<float>());
803         } else {
804             ImageModel::GetInstance()->SetColorFilterMatrix(DEFAULT_COLORFILTER_MATRIX);
805             return;
806         }
807     }
808     ImageModel::GetInstance()->SetColorFilterMatrix(colorfilter);
809 }
810 
SetSmoothEdge(const JSCallbackInfo & info)811 void JSImage::SetSmoothEdge(const JSCallbackInfo& info)
812 {
813     if (info.Length() != 1) {
814         ImageModel::GetInstance()->SetSmoothEdge(DEFAULT_SMOOTHEDGE_VALUE);
815         return;
816     }
817     double parseRes = DEFAULT_SMOOTHEDGE_VALUE;
818     ParseJsDouble(info[0], parseRes);
819     // Effective range : (FLOOR_SMOOTHEDGE_VALUE, CEIL_SMOOTHEDGE_VALUE]
820     // otherwise: DEFAULT_SMOOTHEDGE_VALUE
821     if (GreatNotEqual(parseRes, CEIL_SMOOTHEDGE_VALUE) || LessNotEqual(parseRes, FLOOR_SMOOTHEDGE_VALUE)) {
822         parseRes = DEFAULT_SMOOTHEDGE_VALUE;
823     }
824     ImageModel::GetInstance()->SetSmoothEdge(static_cast<float>(parseRes));
825 }
826 
SetDynamicRangeMode(const JSCallbackInfo & info)827 void JSImage::SetDynamicRangeMode(const JSCallbackInfo& info)
828 {
829     if (info.Length() < 1) {
830         ImageModel::GetInstance()->SetDynamicRangeMode(DynamicRangeMode::STANDARD);
831         return;
832     }
833     int32_t parseRes = static_cast<int32_t>(DynamicRangeMode::STANDARD);
834     ParseJsInteger(info[0], parseRes);
835     if (parseRes < static_cast<int32_t>(DynamicRangeMode::HIGH) ||
836         parseRes > static_cast<int32_t>(DynamicRangeMode::STANDARD)) {
837         parseRes = static_cast<int32_t>(DynamicRangeMode::STANDARD);
838     }
839     DynamicRangeMode dynamicRangeMode = static_cast<DynamicRangeMode>(parseRes);
840     ImageModel::GetInstance()->SetDynamicRangeMode(dynamicRangeMode);
841 }
842 
SetEnhancedImageQuality(const JSCallbackInfo & info)843 void JSImage::SetEnhancedImageQuality(const JSCallbackInfo& info)
844 {
845     if (info.Length() < 1) {
846         ImageModel::GetInstance()->SetEnhancedImageQuality(AIImageQuality::LOW);
847         return;
848     }
849     int32_t parseRes = static_cast<int32_t>(AIImageQuality::LOW);
850     ParseJsInteger(info[0], parseRes);
851     if (parseRes < static_cast<int32_t>(AIImageQuality::LOW) || parseRes > static_cast<int32_t>(AIImageQuality::HIGH)) {
852         parseRes = static_cast<int32_t>(AIImageQuality::LOW);
853     }
854     AIImageQuality resolutionQuality = static_cast<AIImageQuality>(parseRes);
855     ImageModel::GetInstance()->SetEnhancedImageQuality(resolutionQuality);
856 }
857 
SetOrientation(const JSCallbackInfo & info)858 void JSImage::SetOrientation(const JSCallbackInfo& info)
859 {
860     if (info.Length() < 1) {
861         ImageModel::GetInstance()->SetOrientation(ImageRotateOrientation::UP);
862         return;
863     }
864     int32_t parseRes = 0;
865     ParseJsInteger(info[0], parseRes);
866     if (parseRes < static_cast<int>(ImageRotateOrientation::AUTO) ||
867         parseRes > static_cast<int>(ImageRotateOrientation::LEFT)) {
868         parseRes = static_cast<int>(ImageRotateOrientation::UP);
869     }
870     auto res = static_cast<ImageRotateOrientation>(parseRes);
871     ImageModel::GetInstance()->SetOrientation(res);
872 }
873 
CreateImageAnimation(std::vector<RefPtr<PixelMap>> & pixelMaps,int32_t duration,int32_t iterations)874 void JSImage::CreateImageAnimation(std::vector<RefPtr<PixelMap>>& pixelMaps, int32_t duration, int32_t iterations)
875 {
876     std::vector<ImageProperties> imageList;
877     for (int i = 0; i < static_cast<int32_t>(pixelMaps.size()); i++) {
878         ImageProperties image;
879         image.pixelMap = pixelMaps[i];
880         imageList.push_back(image);
881     }
882     ImageModel::GetInstance()->CreateAnimation(imageList, duration, iterations);
883 }
884 
JSBind(BindingTarget globalObj)885 void JSImage::JSBind(BindingTarget globalObj)
886 {
887     JSClass<JSImage>::Declare("Image");
888     MethodOptions opt = MethodOptions::NONE;
889     JSClass<JSImage>::StaticMethod("create", &JSImage::Create, opt);
890     JSClass<JSImage>::StaticMethod("alt", &JSImage::SetAlt, opt);
891     JSClass<JSImage>::StaticMethod("objectFit", &JSImage::SetObjectFit, opt);
892     JSClass<JSImage>::StaticMethod("imageMatrix", &JSImage::SetImageMatrix, opt);
893     JSClass<JSImage>::StaticMethod("matchTextDirection", &JSImage::SetMatchTextDirection, opt);
894     JSClass<JSImage>::StaticMethod("fitOriginalSize", &JSImage::SetFitOriginalSize, opt);
895     JSClass<JSImage>::StaticMethod("sourceSize", &JSImage::SetSourceSize, opt);
896     JSClass<JSImage>::StaticMethod("fillColor", &JSImage::SetImageFill, opt);
897     JSClass<JSImage>::StaticMethod("renderMode", &JSImage::SetImageRenderMode, opt);
898     JSClass<JSImage>::StaticMethod("objectRepeat", &JSImage::SetImageRepeat, opt);
899     JSClass<JSImage>::StaticMethod("interpolation", &JSImage::SetImageInterpolation, opt);
900     JSClass<JSImage>::StaticMethod("colorFilter", &JSImage::SetColorFilter, opt);
901     JSClass<JSImage>::StaticMethod("edgeAntialiasing", &JSImage::SetSmoothEdge, opt);
902     JSClass<JSImage>::StaticMethod("dynamicRangeMode", &JSImage::SetDynamicRangeMode, opt);
903     JSClass<JSImage>::StaticMethod("enhancedImageQuality", &JSImage::SetEnhancedImageQuality, opt);
904     JSClass<JSImage>::StaticMethod("orientation", &JSImage::SetOrientation, opt);
905 
906     JSClass<JSImage>::StaticMethod("border", &JSImage::JsBorder);
907     JSClass<JSImage>::StaticMethod("borderRadius", &JSImage::JsBorderRadius);
908     JSClass<JSImage>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
909     JSClass<JSImage>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
910     JSClass<JSImage>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
911     JSClass<JSImage>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
912     JSClass<JSImage>::StaticMethod("autoResize", &JSImage::SetAutoResize);
913     JSClass<JSImage>::StaticMethod("resizable", &JSImage::JsImageResizable);
914 
915     JSClass<JSImage>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
916     JSClass<JSImage>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
917     JSClass<JSImage>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
918     JSClass<JSImage>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
919     JSClass<JSImage>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
920     JSClass<JSImage>::StaticMethod("onComplete", &JSImage::OnComplete);
921     JSClass<JSImage>::StaticMethod("onError", &JSImage::OnError);
922     JSClass<JSImage>::StaticMethod("onFinish", &JSImage::OnFinish);
923     JSClass<JSImage>::StaticMethod("syncLoad", &JSImage::SetSyncLoad);
924     JSClass<JSImage>::StaticMethod("remoteMessage", &JSInteractableView::JsCommonRemoteMessage);
925     JSClass<JSImage>::StaticMethod("draggable", &JSImage::JsSetDraggable);
926     JSClass<JSImage>::StaticMethod("onDragStart", &JSImage::JsOnDragStart);
927     JSClass<JSImage>::StaticMethod("copyOption", &JSImage::SetCopyOption);
928     JSClass<JSImage>::StaticMethod("enableAnalyzer", &JSImage::EnableAnalyzer);
929     JSClass<JSImage>::StaticMethod("analyzerConfig", &JSImage::AnalyzerConfig);
930 
931     // override method
932     JSClass<JSImage>::StaticMethod("opacity", &JSImage::JsOpacity);
933     JSClass<JSImage>::StaticMethod("blur", &JSImage::JsBlur);
934     JSClass<JSImage>::StaticMethod("transition", &JSImage::JsTransition);
935     JSClass<JSImage>::StaticMethod("pointLight", &JSViewAbstract::JsPointLight, opt);
936     JSClass<JSImage>::InheritAndBind<JSViewAbstract>(globalObj);
937 
938     JSClass<JSColorFilter>::Declare("ColorFilter");
939     JSClass<JSColorFilter>::Bind(globalObj, JSColorFilter::ConstructorCallback, JSColorFilter::DestructorCallback);
940 }
941 
JsSetDraggable(bool draggable)942 void JSImage::JsSetDraggable(bool draggable)
943 {
944     ImageModel::GetInstance()->SetDraggable(draggable);
945 }
946 
JsOnDragStart(const JSCallbackInfo & info)947 void JSImage::JsOnDragStart(const JSCallbackInfo& info)
948 {
949     if (!Container::LessThanAPITargetVersion(PlatformVersion::VERSION_FIFTEEN)) {
950         JSViewAbstract::JsOnDragStart(info);
951         return;
952     }
953     if (info.Length() != 1 || !info[0]->IsFunction()) {
954         return;
955     }
956     RefPtr<JsDragFunction> jsOnDragStartFunc = AceType::MakeRefPtr<JsDragFunction>(JSRef<JSFunc>::Cast(info[0]));
957     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
958     auto onDragStartId = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragStartFunc), node = frameNode](
959                              const RefPtr<DragEvent>& info, const std::string& extraParams) -> NG::DragDropBaseInfo {
960         NG::DragDropBaseInfo itemInfo;
961         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, itemInfo);
962         PipelineContext::SetCallBackNode(node);
963         auto ret = func->Execute(info, extraParams);
964         if (!ret->IsObject()) {
965             return itemInfo;
966         }
967         if (ParseAndUpdateDragItemInfo(ret, itemInfo)) {
968             return itemInfo;
969         }
970 
971         auto builderObj = JSRef<JSObject>::Cast(ret);
972 #if defined(PIXEL_MAP_SUPPORTED)
973         auto pixmap = builderObj->GetProperty("pixelMap");
974         itemInfo.pixelMap = CreatePixelMapFromNapiValue(pixmap);
975 #endif
976         auto extraInfo = builderObj->GetProperty("extraInfo");
977         ParseJsString(extraInfo, itemInfo.extraInfo);
978         ParseAndUpdateDragItemInfo(builderObj->GetProperty("builder"), itemInfo);
979         return itemInfo;
980     };
981     ImageModel::GetInstance()->SetOnDragStart(std::move(onDragStartId));
982 }
983 
SetCopyOption(const JSCallbackInfo & info)984 void JSImage::SetCopyOption(const JSCallbackInfo& info)
985 {
986     if (ImageModel::GetInstance()->GetIsAnimation()) {
987         return;
988     }
989     auto copyOptions = CopyOptions::None;
990     if (info[0]->IsNumber()) {
991         auto enumNumber = info[0]->ToNumber<int>();
992         copyOptions = static_cast<CopyOptions>(enumNumber);
993         if (copyOptions < CopyOptions::None || copyOptions > CopyOptions::Distributed) {
994             copyOptions = CopyOptions::None;
995         }
996     }
997     ImageModel::GetInstance()->SetCopyOption(copyOptions);
998 }
999 
EnableAnalyzer(bool isEnableAnalyzer)1000 void JSImage::EnableAnalyzer(bool isEnableAnalyzer)
1001 {
1002     if (ImageModel::GetInstance()->GetIsAnimation()) {
1003         return;
1004     }
1005     ImageModel::GetInstance()->EnableAnalyzer(isEnableAnalyzer);
1006 }
1007 
AnalyzerConfig(const JSCallbackInfo & info)1008 void JSImage::AnalyzerConfig(const JSCallbackInfo& info)
1009 {
1010     auto configParams = info[0];
1011     if (configParams->IsNull() || !configParams->IsObject()) {
1012         return;
1013     }
1014     auto engine = EngineHelper::GetCurrentEngine();
1015     CHECK_NULL_VOID(engine);
1016     NativeEngine* nativeEngine = engine->GetNativeEngine();
1017     CHECK_NULL_VOID(nativeEngine);
1018     panda::Local<JsiValue> value = configParams.Get().GetLocalHandle();
1019     JSValueWrapper valueWrapper = value;
1020     ScopeRAII scope(reinterpret_cast<napi_env>(nativeEngine));
1021     napi_value nativeValue = nativeEngine->ValueToNapiValue(valueWrapper);
1022     ImageModel::GetInstance()->SetImageAnalyzerConfig(nativeValue);
1023 
1024     // As an example, the function is not in effect.
1025     auto paramObject = JSRef<JSObject>::Cast(configParams);
1026     JSRef<JSVal> typeVal = paramObject->GetProperty("types");
1027     ImageAnalyzerConfig analyzerConfig;
1028     if (typeVal->IsArray()) {
1029         auto array = JSRef<JSArray>::Cast(typeVal);
1030         std::set<ImageAnalyzerType> types;
1031         for (size_t i = 0; i < array->Length(); ++i) {
1032             if (!array->GetValueAt(i)->IsNumber()) {
1033                 continue;
1034             }
1035             int value = array->GetValueAt(i)->ToNumber<int>();
1036             ImageAnalyzerType type = static_cast<ImageAnalyzerType>(value);
1037             if (type != ImageAnalyzerType::SUBJECT && type != ImageAnalyzerType::TEXT) {
1038                 continue;
1039             }
1040             types.insert(type);
1041         }
1042         analyzerConfig.types = std::move(types);
1043     }
1044     ImageModel::GetInstance()->SetImageAnalyzerConfig(analyzerConfig);
1045 }
1046 
1047 } // namespace OHOS::Ace::Framework
1048