!46108 动态照片组件支持AI抠图场景

Merge pull request !46108 from 大山/master
This commit is contained in:
openharmony_ci 2024-10-22 13:43:22 +00:00 committed by Gitee
commit 64c6f9b693
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
30 changed files with 847 additions and 6 deletions

View File

@ -18,14 +18,39 @@
#if !defined(PREVIEW)
#include <dlfcn.h>
#endif
#include <variant>
#include "data_ability_helper.h"
#include "base/log/ace_trace.h"
#include "base/utils/string_utils.h"
#include "utils.h"
namespace OHOS::Ace {
const std::string MEDIA_SERVER_HEAD = "datashare:///media";
const std::string IMAGE_PATH_DATA = "data";
const std::string MOVINGPHOTO_IMAGE_COVERPOSITION = "cover_positon";
const std::string IMAGE_URI = "uri";
template<typename ResultSet>
static inline std::string GetStringVal(const std::string &field, const ResultSet &result)
{
return std::get<std::string>(ResultSetUtils::GetValFromColumn(field, result, ResultSetDataType::TYPE_STRING));
}
template<typename ResultSet>
static inline int32_t GetInt32Val(const std::string &field, const ResultSet &result)
{
return std::get<int32_t>(ResultSetUtils::GetValFromColumn(field, result, ResultSetDataType::TYPE_INT32));
}
template<typename ResultSet>
static inline int64_t GetInt64Val(const std::string &field, const ResultSet &result)
{
return std::get<int64_t>(ResultSetUtils::GetValFromColumn(field, result, ResultSetDataType::TYPE_INT64));
}
template<typename ResultSet>
static inline double GetDoubleVal(const std::string &field, const ResultSet &result)
{
return std::get<double>(ResultSetUtils::GetValFromColumn(field, result, ResultSetDataType::TYPE_DOUBLE));
}
DataAbilityHelperStandard::DataAbilityHelperStandard(const std::shared_ptr<OHOS::AppExecFwk::Context>& context,
const std::shared_ptr<OHOS::AbilityRuntime::Context>& runtimeContext, bool useStageModel)
@ -77,6 +102,40 @@ int64_t DataAbilityHelperStandard::GetMovingPhotoDateModified(const std::string&
#endif
}
int64_t DataAbilityHelperStandard::GetMovingPhotoCoverPosition(const std::string& columnName,
const std::string& value,
std::vector<std::string>& columns)
{
#ifdef MEDIA_LIBRARY_EXISTS
auto resultSet = mgr_.GetResultSetFromDb(columnName, value, columns);
if (resultSet == nullptr || resultSet->GoToFirstRow() != 0) {
LOGE("Result is nullptr or GoToFirstRow failed.");
return -1;
}
int64_t coverPosition = GetInt64Val(MOVINGPHOTO_IMAGE_COVERPOSITION, resultSet);
return coverPosition;
#else
return -1;
#endif
}
std::string DataAbilityHelperStandard::GetMovingPhotoImagePath(const std::string& uri)
{
#ifdef MEDIA_LIBRARY_EXISTS
std::vector<std::string> columns = {IMAGE_PATH_DATA};
auto resultSet = mgr_.GetResultSetFromDb(IMAGE_URI, uri, columns);
if (resultSet == nullptr || resultSet->GoToFirstRow() != 0) {
LOGE("Result is nullptr or GoToFirstRow failed.");
return "";
}
std::string path = GetStringVal(IMAGE_PATH_DATA, resultSet);
LOGI("resultSet path : %{public}s.", path.c_str());
return path;
#else
return "";
#endif
}
int32_t DataAbilityHelperStandard::OpenFile(const std::string& uriStr, const std::string& mode)
{
// FA model always uses DataAbility

View File

@ -23,6 +23,7 @@
#endif
#include "pixel_map.h"
#include "datashare_result_set.h"
namespace OHOS::AppExecFwk {
class DataAbilityHelper;
@ -56,6 +57,9 @@ public:
int32_t ReadMovingPhotoVideo(const std::string &uri) override;
std::string GetMovingPhotoImageUri(const std::string& uri) override;
int64_t GetMovingPhotoDateModified(const std::string& uri) override;
int64_t GetMovingPhotoCoverPosition(const std::string& columnName, const std::string& value,
std::vector<std::string>& columns) override;
std::string GetMovingPhotoImagePath(const std::string& uri) override;
private:
int32_t OpenFileWithDataAbility(const std::string& uriStr, const std::string& mode);

View File

@ -54,6 +54,118 @@ inline const std::string GenerateFullPath(const std::string& prePath, const std:
return fullPath;
}
enum class ResultSetDataType {
TYPE_NULL = 0,
TYPE_STRING,
TYPE_INT32,
TYPE_INT64,
TYPE_DOUBLE
};
class ResultSetUtils {
public:
template<typename T>
static std::variant<int32_t, std::string, int64_t, double> GetValFromColumn(const std::string &columnName,
T &resultSet, ResultSetDataType type)
{
if (resultSet == nullptr) {
return DefaultVariantVal(type);
}
int32_t err = 0;
int32_t index = 0;
err = resultSet->GetColumnIndex(columnName, index);
if (err) {
return DefaultVariantVal(type);
}
std::variant<int32_t, std::string, int64_t, double> data;
switch (type) {
case ResultSetDataType::TYPE_STRING: {
data = GetStringValFromColumn(index, resultSet);
break;
}
case ResultSetDataType::TYPE_INT32: {
data = GetIntValFromColumn(index, resultSet);
break;
}
case ResultSetDataType::TYPE_INT64: {
data = GetLongValFromColumn(index, resultSet);
break;
}
case ResultSetDataType::TYPE_DOUBLE: {
data = GetDoubleValFromColumn(index, resultSet);
break;
}
default: {
return DefaultVariantVal(type);
break;
}
}
return data;
}
template<typename T>
static inline std::string GetStringValFromColumn(int index, T &resultSet)
{
std::string stringVal;
if (resultSet->GetString(index, stringVal)) {
return "";
}
return stringVal;
}
template<typename T>
static inline int32_t GetIntValFromColumn(int index, T &resultSet)
{
int32_t integerVal;
if (resultSet->GetInt(index, integerVal)) {
return 0;
}
return integerVal;
}
template<typename T>
static inline int64_t GetLongValFromColumn(int index, T &resultSet)
{
int64_t integer64Val;
if (resultSet->GetLong(index, integer64Val)) {
return 0;
}
return integer64Val;
}
template<typename T>
static inline double GetDoubleValFromColumn(int index, T &resultSet)
{
double doubleVal;
if (resultSet->GetDouble(index, doubleVal)) {
return 0;
}
return doubleVal;
}
private:
static std::variant<int32_t, std::string, int64_t, double> DefaultVariantVal(ResultSetDataType type)
{
switch (type) {
case ResultSetDataType::TYPE_STRING:
return std::string();
case ResultSetDataType::TYPE_INT32:
return 0;
case ResultSetDataType::TYPE_INT64:
return static_cast<int64_t>(0);
case ResultSetDataType::TYPE_DOUBLE:
return static_cast<double>(0.0);
default:
return 0;
}
return 0;
}
};
NG::SafeAreaInsets ConvertAvoidArea(const OHOS::Rosen::AvoidArea& avoidArea);
Rect ConvertDMRect2Rect(const OHOS::Rosen::DMRect& displayAvailableRect);
} // namespace OHOS::Ace

View File

@ -80,6 +80,48 @@ void ImageAnalyzerManager::CreateAnalyzerOverlay(const RefPtr<OHOS::Ace::PixelMa
analyzerUIConfig_.onAnalyzed = std::nullopt;
}
void ImageAnalyzerManager::CreateMovingPhotoAnalyzerOverlay(const RefPtr<OHOS::Ace::PixelMap>& pixelMap,
MovingPhotoAnalyzerInfo info)
{
CHECK_NULL_VOID(imageAnalyzerAdapter_);
void* pixelmapNapiVal = nullptr;
CHECK_NULL_VOID(pixelMap);
pixelmapNapiVal = imageAnalyzerAdapter_->ConvertPixmapNapi(pixelMap);
analyzerUIConfig_.holder = holder_;
analyzerUIConfig_.contentWidth = info.contentWidth;
analyzerUIConfig_.contentHeight = info.contentHeight;
analyzerUIConfig_.pixelMapWidth = pixelMap->GetWidth();
analyzerUIConfig_.pixelMapHeight = pixelMap->GetHeight();
RefPtr<NG::UINode> customNode;
{
NG::ScopedViewStackProcessor builderViewStackProcessor;
auto analyzerConfig = imageAnalyzerAdapter_->GetImageAnalyzerConfig();
ImageAnalyzerMgr::GetInstance().BuildNodeFunc(info.uri, pixelmapNapiVal,
info.frameTimestamp, analyzerConfig, &analyzerUIConfig_, &overlayData_);
customNode = NG::ViewStackProcessor::GetInstance()->Finish();
}
auto overlayNode = AceType::DynamicCast<NG::FrameNode>(customNode);
CHECK_NULL_VOID(overlayNode);
auto node = frameNode_.Upgrade();
CHECK_NULL_VOID(node);
node->SetOverlayNode(overlayNode);
overlayNode->SetParent(AceType::WeakClaim(AceType::RawPtr(node)));
overlayNode->SetActive(true);
UpdateAnalyzerOverlayLayout();
auto renderContext = overlayNode->GetRenderContext();
CHECK_NULL_VOID(renderContext);
renderContext->UpdateZIndex(INT32_MAX);
overlayNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE_SELF);
isAnalyzerOverlayBuild_ = true;
CHECK_NULL_VOID(analyzerUIConfig_.onAnalyzed);
(analyzerUIConfig_.onAnalyzed.value())(ImageAnalyzerState::FINISHED);
analyzerUIConfig_.onAnalyzed = std::nullopt;
}
void ImageAnalyzerManager::UpdateAnalyzerOverlay(const RefPtr<OHOS::Ace::PixelMap>& pixelMap,
const NG::OffsetF& offset)
{
@ -118,6 +160,40 @@ void ImageAnalyzerManager::UpdateAnalyzerOverlay(const RefPtr<OHOS::Ace::PixelMa
overlayNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE_SELF);
}
void ImageAnalyzerManager::UpdateMovingPhotoAnalyzerOverlay(const RefPtr<OHOS::Ace::PixelMap>& pixelMap,
MovingPhotoAnalyzerInfo info)
{
if (!isAnalyzerOverlayBuild_) {
return;
}
auto node = frameNode_.Upgrade();
CHECK_NULL_VOID(node);
if (holder_ == ImageAnalyzerHolder::IMAGE) {
auto imagePattern = AceType::DynamicCast<NG::ImagePattern>(node->GetPattern());
CHECK_NULL_VOID(imagePattern);
if (!imagePattern->hasSceneChanged()) {
return;
}
}
CHECK_NULL_VOID(pixelMap);
analyzerUIConfig_.holder = holder_;
analyzerUIConfig_.contentWidth = info.contentWidth;
analyzerUIConfig_.contentHeight = info.contentHeight;
analyzerUIConfig_.pixelMapWidth = pixelMap->GetWidth();
analyzerUIConfig_.pixelMapHeight = pixelMap->GetHeight();
CHECK_NULL_VOID(imageAnalyzerAdapter_);
auto pixelmapNapiVal = imageAnalyzerAdapter_->ConvertPixmapNapi(pixelMap);
auto overlayNode = node->GetOverlayNode();
CHECK_NULL_VOID(overlayNode);
auto analyzerConfig = imageAnalyzerAdapter_->GetImageAnalyzerConfig();
ImageAnalyzerMgr::GetInstance().UpdateImage(&overlayData_, info.uri, pixelmapNapiVal,
info.frameTimestamp, analyzerConfig, &analyzerUIConfig_);
overlayNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE_SELF);
}
void ImageAnalyzerManager::DestroyAnalyzerOverlay()
{
ReleaseImageAnalyzer();
@ -386,4 +462,10 @@ void ImageAnalyzerManager::SetNotifySelectedCallback(
{
analyzerUIConfig_.onNotifySelectedStatus = std::move(callback);
}
void ImageAnalyzerManager::SetOnCanPlayCallback(
OnCanPlayCallback&& onCanPlay)
{
analyzerUIConfig_.onCanPlay = std::move(onCanPlay);
}
} // namespace OHOS::Ace

View File

@ -51,6 +51,13 @@ void ImageAnalyzerMgr::BuildNodeFunc(
return engine_->BuildNodeFunc(pixelMap, config, uiConfig, overlayData);
}
}
void ImageAnalyzerMgr::BuildNodeFunc(std::string uri, void* pixelMap, int frameTimestamp,
void* config, ImageAnalyzerInnerConfig* uiConfig, void** overlayData)
{
if (engine_) {
return engine_->BuildNodeFunc(uri, pixelMap, frameTimestamp, config, uiConfig, overlayData);
}
}
void ImageAnalyzerMgr::UpdateImage(
void** overlayData, void* pixelMap, void* config, ImageAnalyzerInnerConfig* uiConfig)
{
@ -58,6 +65,13 @@ void ImageAnalyzerMgr::UpdateImage(
return engine_->UpdateImage(overlayData, pixelMap, config, uiConfig);
}
}
void ImageAnalyzerMgr::UpdateImage(void** overlayData, std::string uri, void* pixelMap,
int frameTimestamp, void* config, ImageAnalyzerInnerConfig* uiConfig)
{
if (engine_) {
return engine_->UpdateImage(overlayData, uri, pixelMap, frameTimestamp, config, uiConfig);
}
}
void ImageAnalyzerMgr::UpdateConfig(void** overlayData, void* config)
{
if (engine_) {

View File

@ -29,11 +29,21 @@ void ImageAnalyzerManager::CreateAnalyzerOverlay(const RefPtr<OHOS::Ace::PixelMa
{
}
void ImageAnalyzerManager::CreateMovingPhotoAnalyzerOverlay(const RefPtr<OHOS::Ace::PixelMap>& pixelMap,
MovingPhotoAnalyzerInfo info)
{
}
void ImageAnalyzerManager::UpdateAnalyzerOverlay(const RefPtr<OHOS::Ace::PixelMap>& pixelMap,
const NG::OffsetF& offset)
{
}
void ImageAnalyzerManager::UpdateMovingPhotoAnalyzerOverlay(const RefPtr<OHOS::Ace::PixelMap>& pixelMap,
MovingPhotoAnalyzerInfo info)
{
}
void ImageAnalyzerManager::DestroyAnalyzerOverlay()
{
}
@ -69,6 +79,10 @@ void ImageAnalyzerManager::SetImageAnalyzerCallback(OnAnalyzedCallback& callback
{
}
void ImageAnalyzerManager::SetOnCanPlayCallback(OnCanPlayCallback&& callback)
{
}
void ImageAnalyzerManager::ReleaseImageAnalyzer()
{
}

View File

@ -40,11 +40,21 @@ void ImageAnalyzerMgr::BuildNodeFunc(
{
}
void ImageAnalyzerMgr::BuildNodeFunc(std::string uri, void* pixelMap, int frameTimestamp,
void* config, ImageAnalyzerInnerConfig* uiConfig, void** overlayData)
{
}
void ImageAnalyzerMgr::UpdateImage(
void** overlayData, void* pixelMap, void* config, ImageAnalyzerInnerConfig* uiConfig)
{
}
void ImageAnalyzerMgr::UpdateImage(void** overlayData, std::string uri, void* pixelMap,
int frameTimestamp, void* config, ImageAnalyzerInnerConfig* uiConfig)
{
}
void ImageAnalyzerMgr::UpdateConfig(void** overlayData, void* config)
{
}

View File

@ -250,6 +250,26 @@
OHOS::Ace::AceScoringLog::*;
"OHOS::Ace::NG::CustomNode::FlushReload()";
"OHOS::Ace::CanvasModel::GetInstance()";
OHOS::Ace::ImageAnalyzerAdapterImpl::*;
OHOS::Ace::ImageAnalyzerLoader::*;
OHOS::Ace::ImageAnalyzerManager::ImageAnalyzerManager*;
OHOS::Ace::ImageAnalyzerManager::IsSupportImageAnalyzerFeature*;
OHOS::Ace::ImageAnalyzerManager::CreateMovingPhotoAnalyzerOverlay*;
OHOS::Ace::ImageAnalyzerManager::UpdateMovingPhotoAnalyzerOverlay*;
OHOS::Ace::ImageAnalyzerManager::UpdateAnalyzerUIConfig*;
OHOS::Ace::ImageAnalyzerManager::DestroyAnalyzerOverlay*;
OHOS::Ace::ImageAnalyzerManager::ReleaseImageAnalyzer*;
OHOS::Ace::ImageAnalyzerManager::SetImageAnalyzerConfig*;
OHOS::Ace::ImageAnalyzerManager::SetImageAIOptions*;
OHOS::Ace::ImageAnalyzerManager::IsOverlayCreated*;
OHOS::Ace::ImageAnalyzerManager::SetOnCanPlayCallback*;
OHOS::Ace::ImageAnalyzerMgr::GetInstance*;
OHOS::Ace::ImageAnalyzerMgr::IsImageAnalyzerSupported*;
OHOS::Ace::ImageAnalyzerMgr::BuildNodeFunc*;
OHOS::Ace::ImageAnalyzerMgr::UpdateImage*;
OHOS::Ace::ImageAnalyzerMgr::UpdateConfig*;
OHOS::Ace::ImageAnalyzerMgr::Release*;
OHOS::Ace::ImageAnalyzerMgr::UpdateOverlayStatus*;
OHOS::Ace::NG::InspectorFilter::*;
OHOS::Ace::NG::ServiceCollaborationMenuAceHelper::*;

View File

@ -56,6 +56,7 @@ ohos_shared_library("movingphotoview") {
include_dirs = [
"${component_ext_path}/ext_common/",
"${component_ext_path}/movingphoto/",
"$ace_root/frameworks/",
]
include_dirs += additional_include_dirs

View File

@ -190,4 +190,22 @@ void MovingPhotoModelNG::RepeatPlay(bool isRepeatPlay)
CHECK_NULL_VOID(movingPhotoPattern);
movingPhotoPattern->RepeatPlay(isRepeatPlay);
}
void MovingPhotoModelNG::EnableAnalyzer(bool enabled)
{
auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
CHECK_NULL_VOID(frameNode);
auto movingPhotoPattern = AceType::DynamicCast<MovingPhotoPattern>(frameNode->GetPattern());
CHECK_NULL_VOID(movingPhotoPattern);
movingPhotoPattern->EnableAnalyzer(enabled);
}
void MovingPhotoModelNG::SetImageAIOptions(void* options)
{
auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
CHECK_NULL_VOID(frameNode);
auto movingPhotoPattern = AceType::DynamicCast<MovingPhotoPattern>(frameNode->GetPattern());
CHECK_NULL_VOID(movingPhotoPattern);
movingPhotoPattern->SetImageAIOptions(options);
}
} // namespace OHOS::Ace::NG

View File

@ -41,6 +41,8 @@ public:
void AutoPlayPeriod(int64_t startTime, int64_t endTime);
void AutoPlay(bool isAutoPlay);
void RepeatPlay(bool isRepeatPlay);
void EnableAnalyzer(bool enabled);
void SetImageAIOptions(void* options);
private:
static std::unique_ptr<MovingPhotoModelNG> instance_;

View File

@ -76,6 +76,10 @@ napi_value JsCreate(napi_env env, napi_callback_info info)
return ExtNapiUtils::CreateNull(env);
}
napi_value jsImageAIOptions = nullptr;
napi_get_named_property(env, argv[0], "imageAIOptions", &jsImageAIOptions);
NG::MovingPhotoModelNG::GetInstance()->SetImageAIOptions(jsImageAIOptions);
napi_value getUri = nullptr;
napi_get_named_property(env, jsData, "getUri", &getUri);
if (!ExtNapiUtils::CheckTypeForNapiValue(env, getUri, napi_function)) {
@ -244,6 +248,7 @@ napi_value InitView(napi_env env, napi_value exports)
DECLARE_NAPI_FUNCTION("autoPlayPeriod", JsAutoPlayPeriod),
DECLARE_NAPI_FUNCTION("autoPlay", JsAutoPlay),
DECLARE_NAPI_FUNCTION("repeatPlay", JsRepeatPlay),
DECLARE_NAPI_FUNCTION("enableAnalyzer", JsEnableAnalyzer),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
return exports;
@ -351,6 +356,22 @@ napi_value JsAutoPlay(napi_env env, napi_callback_info info)
return ExtNapiUtils::CreateNull(env);
}
napi_value JsEnableAnalyzer(napi_env env, napi_callback_info info)
{
size_t argc = MAX_ARG_NUM;
napi_value argv[MAX_ARG_NUM] = { nullptr };
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
NAPI_ASSERT(env, argc >= ARG_NUM_ONE, "Wrong number of arguments");
bool enabled = false;
if (ExtNapiUtils::CheckTypeForNapiValue(env, argv[PARAM_INDEX_ZERO], napi_boolean)) {
enabled = ExtNapiUtils::GetBool(env, argv[PARAM_INDEX_ZERO]);
}
NG::MovingPhotoModelNG::GetInstance()->EnableAnalyzer(enabled);
return ExtNapiUtils::CreateNull(env);
}
napi_value JsRepeatPlay(napi_env env, napi_callback_info info)
{
size_t argc = MAX_ARG_NUM;

View File

@ -34,6 +34,7 @@ napi_value StopPlayback(napi_env env, napi_callback_info info);
napi_value JsAutoPlayPeriod(napi_env env, napi_callback_info info);
napi_value JsAutoPlay(napi_env env, napi_callback_info info);
napi_value JsRepeatPlay(napi_env env, napi_callback_info info);
napi_value JsEnableAnalyzer(napi_env env, napi_callback_info info);
napi_value MovingPhotoControllerConstructor(napi_env env, napi_callback_info info);
} // namespace OHOS::Ace
#endif // COMPONENT_EXT_MOVING_PHOTO_MOVING_PHOTO_NAPI_H

View File

@ -19,6 +19,7 @@
#include "movingphoto_node.h"
#include "movingphoto_utils.h"
#include "base/image/pixel_map.h"
#include "core/components_ng/pattern/image/image_pattern.h"
namespace OHOS::Ace::NG {
@ -36,6 +37,12 @@ constexpr int64_t VIDEO_PLAYTIME_START_POSITION = 0;
constexpr int64_t VIDEO_PLAYTIME_END_POSITION = 3000;
constexpr int32_t IMAGE_LOADING_COMPLETE = 0;
constexpr int32_t DURATION_FLAG = -1;
const std::string THUMBNAIL_MEDIUM_JOINT = "?&oper=thumbnail&width=-1&height=-1&path=";
const std::string COVER_POSITION = "cover_positon";
const std::string IMAGE_URI = "uri";
constexpr int32_t ANALYZER_DELAY_TIME = 100;
constexpr int32_t ANALYZER_CAPTURE_DELAY_TIME = 1000;
constexpr int32_t AVERAGE_VALUE = 2;
}
MovingPhotoPattern::MovingPhotoPattern(const RefPtr<MovingPhotoController>& controller)
: instanceId_(Container::CurrentId()), controller_(controller)
@ -56,6 +63,7 @@ void MovingPhotoPattern::OnModifyDone()
}
InitEvent();
UpdatePlayMode();
HandleImageAnalyzerMode();
}
void MovingPhotoPattern::OnAttachToFrameNode()
@ -169,12 +177,36 @@ void MovingPhotoPattern::InitEvent()
gestureHub->AddTouchEvent(touchEvent_);
}
void MovingPhotoPattern::LongPressEventModify(bool status)
{
auto host = GetHost();
CHECK_NULL_VOID(host);
auto gestureHub = host->GetOrCreateGestureEventHub();
CHECK_NULL_VOID(gestureHub);
if (status) {
auto longPressCallback = [weak = WeakClaim(this)](GestureEvent& info) {
auto pattern = weak.Upgrade();
CHECK_NULL_VOID(pattern);
pattern->HandleLongPress(info);
};
longPressEvent_ = MakeRefPtr<LongPressEvent>(std::move(longPressCallback));
gestureHub->SetLongPressEvent(longPressEvent_, false, false, LONG_PRESS_DELAY);
} else {
gestureHub->SetLongPressEvent(nullptr);
longPressEvent_ = nullptr;
}
}
void MovingPhotoPattern::HandleLongPress(GestureEvent& info)
{
isFastKeyUp_ = false;
if (currentPlayStatus_ == PlaybackStatus::STARTED || !isPrepared_ || isPlayByController_) {
return;
}
if (autoAndRepeatLevel_ == PlaybackMode::NONE && isEnableAnalyzer_) {
TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "HandleLongPress isEnableAnalyzer_ return.");
return;
}
if (autoAndRepeatLevel_ != PlaybackMode::NONE) {
TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "HandleLongPress auto&Repeat return.");
return;
@ -204,12 +236,16 @@ void MovingPhotoPattern::HandleTouchEvent(TouchEventInfo& info)
ResetMediaPlayer();
}
if (autoAndRepeatLevel_ != PlaybackMode::NONE) {
TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "HandleLongPress auto&Repeat return.");
TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "HandleTouchEvent auto&Repeat return.");
return;
}
if (!isPrepared_ || isPlayByController_) {
return;
}
if (autoAndRepeatLevel_ == PlaybackMode::NONE && isEnableAnalyzer_) {
TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "HandleTouchEvent isEnableAnalyzer_ return.");
return;
}
auto touchList = info.GetChangedTouches();
CHECK_NULL_VOID(!touchList.empty());
auto touchInfo = touchList.front();
@ -470,6 +506,23 @@ void MovingPhotoPattern::UpdatePlayMode()
}
}
void MovingPhotoPattern::HandleImageAnalyzerMode()
{
TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto HandleImageAnalyzerMode.");
if (isEnableAnalyzer_ && autoAndRepeatLevel_ == PlaybackMode::NONE) {
if (!imageAnalyzerManager_) {
EnableAnalyzer(isEnableAnalyzer_);
}
if (imageAnalyzerManager_ && !GetAnalyzerState()) {
StartImageAnalyzer();
}
}
if (!isEnableAnalyzer_ && IsSupportImageAnalyzer()) {
DestroyAnalyzerOverlay();
LongPressEventModify(true);
}
}
void MovingPhotoPattern::MediaResetToPlay()
{
autoAndRepeatLevel_ = historyAutoAndRepeatLevel_;
@ -564,6 +617,7 @@ void MovingPhotoPattern::OnStartedStatusCallback()
bool MovingPhotoPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config)
{
TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer OnStartedStatusCallback.");
if (config.skipMeasure || dirty->SkipMeasureContent()) {
return false;
}
@ -578,6 +632,32 @@ bool MovingPhotoPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& d
(movingPhotoNodeSize.Height() - videoFrameSize.Height()) / HALF, videoFrameSize.Width(),
videoFrameSize.Height());
}
if (IsSupportImageAnalyzer() && isEnableAnalyzer_ && autoAndRepeatLevel_ == PlaybackMode::NONE) {
if (imageAnalyzerManager_ && !GetAnalyzerState()) {
StartImageAnalyzer();
} else {
Rect tmpRect;
auto padding = layoutProperty->CreatePaddingAndBorder();
auto imageFit = layoutProperty->GetObjectFitValue(ImageFit::COVER);
if (imageFit == ImageFit::COVER || imageFit == ImageFit::NONE) {
tmpRect = Rect(padding.left.value_or(0), padding.top.value_or(0),
movingPhotoNodeSize.Width(), movingPhotoNodeSize.Height());
} else {
tmpRect = Rect(
(movingPhotoNodeSize.Width() - videoFrameSize.Width()) / AVERAGE_VALUE + padding.left.value_or(0),
(movingPhotoNodeSize.Height() - videoFrameSize.Height()) / AVERAGE_VALUE + padding.top.value_or(0),
videoFrameSize.Width(), videoFrameSize.Height());
}
contentRect_ = tmpRect;
UpdateAnalyzerUIConfig(geometryNode);
}
}
if (IsSupportImageAnalyzer() && !isEnableAnalyzer_) {
DestroyAnalyzerOverlay();
LongPressEventModify(true);
}
auto host = GetHost();
CHECK_NULL_RETURN(host, false);
host->MarkNeedSyncRenderTree();
@ -1002,6 +1082,9 @@ void MovingPhotoPattern::StopAnimationCallback()
} else if (autoAndRepeatLevel_ == PlaybackMode::AUTO) {
autoAndRepeatLevel_ = PlaybackMode::NONE;
}
if (historyAutoAndRepeatLevel_ == PlaybackMode::AUTO) {
HandleImageAnalyzerMode();
}
}
void MovingPhotoPattern::AutoPlay(bool isAutoPlay)
@ -1015,6 +1098,11 @@ void MovingPhotoPattern::AutoPlay(bool isAutoPlay)
if (autoAndRepeatLevel_ != PlaybackMode::REPEAT) {
historyAutoAndRepeatLevel_ = PlaybackMode::AUTO;
autoAndRepeatLevel_ = PlaybackMode::AUTO;
if (!isSetAutoPlayPeriod_ && (currentPlayStatus_ == PlaybackStatus::PLAYBACK_COMPLETE ||
currentPlayStatus_ == PlaybackStatus::PAUSED)) {
isSetAutoPlayPeriod_ = true;
SetAutoPlayPeriod(autoPlayPeriodStartTime_, autoPlayPeriodEndTime_);
}
}
}
}
@ -1100,6 +1188,34 @@ void MovingPhotoPattern::SetAutoPlayPeriod(int64_t startTime, int64_t endTime)
mediaPlayer_->SetPlayRange(startTime, endTime);
}
void MovingPhotoPattern::HandleImageAnalyzerPlayCallBack()
{
TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "HandleImageAnalyzerPlayCallBack start.");
isFastKeyUp_ = false;
if (currentPlayStatus_ == PlaybackStatus::STARTED || !isPrepared_ || isPlayByController_) {
return;
}
if (autoAndRepeatLevel_ != PlaybackMode::NONE) {
TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "HandleImageAnalyzerPlayCallBack auto&Repeat return.");
return;
}
if (!mediaPlayer_ || !mediaPlayer_->IsMediaPlayerValid()) {
TAG_LOGW(AceLogTag::ACE_MOVING_PHOTO, "MediaPlayer is null or invalid.");
FireMediaPlayerError();
return;
}
if (currentPlayStatus_ == PlaybackStatus::STOPPED) {
mediaPlayer_->PrepareAsync();
}
if (isSetAutoPlayPeriod_ && (currentPlayStatus_ == PlaybackStatus::PLAYBACK_COMPLETE ||
currentPlayStatus_ == PlaybackStatus::PAUSED)) {
int32_t duration = DURATION_FLAG;
mediaPlayer_->GetDuration(duration);
SetAutoPlayPeriod(PERIOD_START, duration);
}
Start();
}
void MovingPhotoPattern::Start()
{
if (!mediaPlayer_ || !mediaPlayer_->IsMediaPlayerValid()) {
@ -1325,8 +1441,254 @@ void MovingPhotoPattern::VisibleAreaCallback(bool visible)
}
}
void MovingPhotoPattern::EnableAnalyzer(bool enable)
{
TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto EnableAnalyzer:%{public}d.", enable);
isEnableAnalyzer_ = enable;
if (!isEnableAnalyzer_) {
DestroyAnalyzerOverlay();
LongPressEventModify(true);
return;
}
CHECK_NULL_VOID(!imageAnalyzerManager_);
auto host = GetHost();
CHECK_NULL_VOID(host);
imageAnalyzerManager_ = std::make_shared<ImageAnalyzerManager>(host, ImageAnalyzerHolder::MOVINGPHOTO);
}
void MovingPhotoPattern::SetImageAIOptions(void* options)
{
TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto SetImageAIOptions");
if (!imageAnalyzerManager_) {
imageAnalyzerManager_ = std::make_shared<ImageAnalyzerManager>(GetHost(), ImageAnalyzerHolder::MOVINGPHOTO);
}
CHECK_NULL_VOID(imageAnalyzerManager_);
imageAnalyzerManager_->SetImageAIOptions(options);
}
bool MovingPhotoPattern::IsSupportImageAnalyzer()
{
TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto IsSupportImageAnalyzer");
auto host = GetHost();
CHECK_NULL_RETURN(host, false);
auto layoutProperty = host->GetLayoutProperty<MovingPhotoLayoutProperty>();
CHECK_NULL_RETURN(layoutProperty, false);
CHECK_NULL_RETURN(imageAnalyzerManager_, false);
return imageAnalyzerManager_->IsSupportImageAnalyzerFeature();
}
bool MovingPhotoPattern::ShouldUpdateImageAnalyzer()
{
TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto ShouldUpdateImageAnalyzer");
auto layoutProperty = GetLayoutProperty<MovingPhotoLayoutProperty>();
CHECK_NULL_RETURN(layoutProperty, false);
const auto& constraint = layoutProperty->GetCalcLayoutConstraint();
if (!constraint || !constraint->selfIdealSize.has_value() || !constraint->selfIdealSize->IsValid()) {
return false;
}
auto selfIdealSize = constraint->selfIdealSize;
if (!selfIdealSize->PercentWidth() && !selfIdealSize->PercentHeight()) {
return false;
}
auto imageFit = layoutProperty->GetObjectFit().value_or(ImageFit::COVER);
if (imageFit != ImageFit::COVER && imageFit != ImageFit::NONE) {
return false;
}
return true;
}
void MovingPhotoPattern::StartImageAnalyzer()
{
TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto StartImageAnalyzer");
if (!IsSupportImageAnalyzer() || !imageAnalyzerManager_) {
return;
}
if (imageAnalyzerManager_->IsOverlayCreated()) {
DestroyAnalyzerOverlay();
LongPressEventModify(true);
}
ContainerScope scope(instanceId_);
auto host = GetHost();
CHECK_NULL_VOID(host);
auto context = host->GetContext();
CHECK_NULL_VOID(context);
auto uiTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
uiTaskExecutor.PostDelayedTask([weak = WeakClaim(this)] {
auto pattern = weak.Upgrade();
CHECK_NULL_VOID(pattern);
pattern->CreateAnalyzerOverlay();
}, ANALYZER_DELAY_TIME, "ArkUIMovingPhotoCreateAnalyzerOverlay");
LongPressEventModify(false);
}
void MovingPhotoPattern::CreateAnalyzerOverlay()
{
TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto CreateAnalyzerOverlay");
CHECK_NULL_VOID(imageAnalyzerManager_);
if (!IsSupportImageAnalyzer() || !imageAnalyzerManager_->IsOverlayCreated()) {
return;
}
GetPixelMap();
int64_t coverPosition = GetUriCoverPosition();
auto onCanPlay = [weak = AceType::WeakClaim(this)](bool canPlay) {
auto pattern = weak.Upgrade();
CHECK_NULL_VOID(pattern);
pattern->HandleAnalyzerPlayEvent(canPlay);
};
auto host = GetHost();
CHECK_NULL_VOID(host);
auto geometryNode = host->GetGeometryNode();
CHECK_NULL_VOID(geometryNode);
auto movingPhotoNodeSize = geometryNode->GetContentSize();
MovingPhotoAnalyzerInfo info = {uri_, coverPosition,
movingPhotoNodeSize.Width(),
movingPhotoNodeSize.Height()};
imageAnalyzerManager_->SetOnCanPlayCallback(std::move(onCanPlay));
imageAnalyzerManager_->CreateMovingPhotoAnalyzerOverlay(pixelMap_, info);
}
void MovingPhotoPattern::StartUpdateImageAnalyzer()
{
TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto StartUpdateImageAnalyzer");
CHECK_NULL_VOID(imageAnalyzerManager_);
if (!imageAnalyzerManager_->IsOverlayCreated()) {
return;
}
UpdateOverlayVisibility(VisibleType::GONE);
ContainerScope scope(instanceId_);
auto host = GetHost();
CHECK_NULL_VOID(host);
auto context = host->GetContext();
CHECK_NULL_VOID(context);
auto uiTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
uiTaskExecutor.PostDelayedTask([weak = WeakClaim(this)] {
auto pattern = weak.Upgrade();
CHECK_NULL_VOID(pattern);
if (!pattern->isContentSizeChanged_) {
return;
}
pattern->UpdateAnalyzerOverlay();
pattern->isContentSizeChanged_ = false;
}, ANALYZER_CAPTURE_DELAY_TIME, "ArkUIMovingPhotoUpdateAnalyzerOverlay");
isContentSizeChanged_ = true;
}
void MovingPhotoPattern::UpdateAnalyzerOverlay()
{
TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto UpdateAnalyzerOverlay");
CHECK_NULL_VOID(imageAnalyzerManager_);
if (!IsSupportImageAnalyzer() || !imageAnalyzerManager_->IsOverlayCreated()) {
return;
}
GetPixelMap();
int64_t coverPosition = GetUriCoverPosition();
UpdateOverlayVisibility(VisibleType::VISIBLE);
auto host = GetHost();
CHECK_NULL_VOID(host);
auto geometryNode = host->GetGeometryNode();
CHECK_NULL_VOID(geometryNode);
auto movingPhotoNodeSize = geometryNode->GetContentSize();
MovingPhotoAnalyzerInfo info = {uri_, coverPosition,
movingPhotoNodeSize.Width(),
movingPhotoNodeSize.Height()};
imageAnalyzerManager_->UpdateMovingPhotoAnalyzerOverlay(pixelMap_, info);
}
void MovingPhotoPattern::UpdateAnalyzerUIConfig(const RefPtr<NG::GeometryNode>& geometryNode)
{
TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto UpdateAnalyzerUIConfig");
if (IsSupportImageAnalyzer()) {
auto layoutProperty = GetLayoutProperty<MovingPhotoLayoutProperty>();
CHECK_NULL_VOID(layoutProperty);
auto padding = layoutProperty->CreatePaddingAndBorder();
OffsetF contentOffset = { contentRect_.Left() - padding.left.value_or(0),
contentRect_.Top() - padding.top.value_or(0) };
PixelMapInfo info = { contentRect_.GetSize().Width(), contentRect_.GetSize().Height(), contentOffset };
CHECK_NULL_VOID(imageAnalyzerManager_);
imageAnalyzerManager_->UpdateAnalyzerUIConfig(geometryNode, info);
}
}
void MovingPhotoPattern::DestroyAnalyzerOverlay()
{
TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto DestroyAnalyzerOverlay");
CHECK_NULL_VOID(imageAnalyzerManager_);
imageAnalyzerManager_->DestroyAnalyzerOverlay();
}
bool MovingPhotoPattern::GetAnalyzerState()
{
TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "movingphoto GetAnalyzerState");
CHECK_NULL_RETURN(imageAnalyzerManager_, false);
return imageAnalyzerManager_->IsOverlayCreated();
}
void MovingPhotoPattern::UpdateOverlayVisibility(VisibleType type)
{
auto host = GetHost();
CHECK_NULL_VOID(host);
auto overlayNode = host->GetOverlayNode();
CHECK_NULL_VOID(overlayNode);
auto prop = overlayNode->GetLayoutProperty();
CHECK_NULL_VOID(prop);
prop->UpdateVisibility(type);
}
void MovingPhotoPattern::GetPixelMap()
{
auto layoutProperty = GetLayoutProperty<MovingPhotoLayoutProperty>();
CHECK_NULL_VOID(layoutProperty);
if (!layoutProperty->HasMovingPhotoUri() || !layoutProperty->HasVideoSource()) {
TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "GetPixelMap MovingPhoto source is null.");
return;
}
auto pipeline = PipelineBase::GetCurrentContext();
CHECK_NULL_VOID(pipeline);
auto dataProvider = AceType::DynamicCast<DataProviderManagerStandard>(pipeline->GetDataProviderManager());
CHECK_NULL_VOID(dataProvider);
std::string imageSrc = dataProvider->GetMovingPhotoImagePath(uri_);
std::string thumbnailUrl = uri_ + THUMBNAIL_MEDIUM_JOINT + imageSrc;
void* pixelMapMediauniquePtr = dataProvider->GetDataProviderThumbnailResFromUri(thumbnailUrl);
CHECK_NULL_VOID(pixelMapMediauniquePtr);
auto pixelMap = PixelMap::CreatePixelMapFromDataAbility(pixelMapMediauniquePtr);
CHECK_NULL_VOID(pixelMap);
pixelMap_ = pixelMap;
}
int64_t MovingPhotoPattern::GetUriCoverPosition()
{
auto pipeline = PipelineBase::GetCurrentContext();
CHECK_NULL_RETURN(pipeline, -1);
auto dataProvider = AceType::DynamicCast<DataProviderManagerStandard>(pipeline->GetDataProviderManager());
CHECK_NULL_RETURN(dataProvider, -1);
std::vector<std::string> columns = {COVER_POSITION};
auto result = dataProvider->GetMovingPhotoCoverPosition(IMAGE_URI, uri_, columns);
return result;
}
void MovingPhotoPattern::HandleAnalyzerPlayEvent(bool canPlay)
{
TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "MovingPhoto HandleAnalyzerPlayEvent:%{public}d", canPlay);
if (isAnalyzerPlaying_ && !canPlay) {
Pause();
StopAnimation();
}
isAnalyzerPlaying_ = canPlay;
if (canPlay) {
HandleImageAnalyzerPlayCallBack();
}
}
MovingPhotoPattern::~MovingPhotoPattern()
{
if (IsSupportImageAnalyzer()) {
TAG_LOGI(AceLogTag::ACE_MOVING_PHOTO, "~MovingPhotoPattern DestroyAnalyzerOverlay.");
DestroyAnalyzerOverlay();
}
if (fd_ > 0) {
close(fd_);
}

View File

@ -22,7 +22,9 @@
#include "movingphoto_controller.h"
#include "movingphoto_utils.h"
#include "base/image/pixel_map.h"
#include "base/memory/referenced.h"
#include "core/common/ai/image_analyzer_manager.h"
#include "core/common/container.h"
#include "core/components_ng/event/event_hub.h"
#include "core/components_ng/event/long_press_event.h"
@ -32,6 +34,7 @@
#include "core/components_ng/render/render_surface.h"
#include "core/components/video/video_utils.h"
#include "core/components/image/image_event.h"
#include "interfaces/inner_api/ace/ai/image_analyzer.h"
namespace OHOS::Ace::NG {
class MovingPhotoPattern : public Pattern {
@ -102,6 +105,12 @@ public:
return currentDateModified_;
}
void EnableAnalyzer(bool enabled);
void SetImageAIOptions(void* options);
bool GetAnalyzerState();
protected:
int32_t instanceId_;
@ -123,12 +132,14 @@ private:
void VisibleAreaCallback(bool visible);
void InitEvent();
void LongPressEventModify(bool status);
void HandleLongPress(GestureEvent& info);
void HandleTouchEvent(TouchEventInfo& info);
void UpdateImageNode();
void UpdateVideoNode();
void UpdatePlayMode();
void HandleImageAnalyzerMode();
SizeF CalculateFitContain(const SizeF& rawSize, const SizeF& layoutSize);
SizeF CalculateFitFill(const SizeF& layoutSize);
SizeF CalculateFitCover(const SizeF& rawSize, const SizeF& layoutSize);
@ -179,15 +190,30 @@ private:
void StartAutoPlay();
void StartRepeatPlay();
void SetAutoPlayPeriod(int64_t startTime, int64_t endTime);
void HandleImageAnalyzerPlayCallBack();
void UpdateMediaPlayerSpeed();
void UpdateMediaPlayerMuted();
void HideImageNode();
bool IsSupportImageAnalyzer();
bool ShouldUpdateImageAnalyzer();
void StartImageAnalyzer();
void StartUpdateImageAnalyzer();
void CreateAnalyzerOverlay();
void DestroyAnalyzerOverlay();
void UpdateAnalyzerOverlay();
void UpdateAnalyzerUIConfig(const RefPtr<NG::GeometryNode>& geometryNode);
void UpdateOverlayVisibility(VisibleType type);
void GetPixelMap();
int64_t GetUriCoverPosition();
void HandleAnalyzerPlayEvent(bool canPlay);
RefPtr<LongPressEvent> longPressEvent_;
RefPtr<TouchEventImpl> touchEvent_;
RefPtr<MovingPhotoController> controller_;
RefPtr<PixelMap> pixelMap_;
int32_t fd_ = -1;
int64_t autoPlayPeriodStartTime_ = -1;
@ -209,7 +235,16 @@ private:
PlaybackMode historyAutoAndRepeatLevel_ = PlaybackMode::NONE;
int64_t currentDateModified_ = -2;
bool isEnableAnalyzer_ = false;
bool isContentSizeChanged_ = false;
bool isAnalyzerCreated_ = false;
bool isPixelMapChanged_ = false;
bool isAnalyzerPlaying_ = false;
Rect lastBoundsRect_;
Rect contentRect_;
std::shared_ptr<ImageAnalyzerManager> imageAnalyzerManager_;
ACE_DISALLOW_COPY_AND_MOVE(MovingPhotoPattern);
};

View File

@ -95,6 +95,10 @@ class MovingPhotoView extends JSViewAbstract {
static repeatPlay(value) {
__MovingPhotoView__.repeatPlay(value);
}
static enableAnalyzer(value) {
__MovingPhotoView__.enableAnalyzer(value);
}
}
export default {

View File

@ -32,6 +32,9 @@ public:
virtual int32_t ReadMovingPhotoVideo(const std::string &uri) { return -1; }
virtual std::string GetMovingPhotoImageUri(const std::string& uri) { return ""; }
virtual int64_t GetMovingPhotoDateModified(const std::string& uri) { return -1; }
virtual int64_t GetMovingPhotoCoverPosition(const std::string& columnName, const std::string& value,
std::vector<std::string>& columns) { return -1; }
virtual std::string GetMovingPhotoImagePath(const std::string& uri) { return ""; }
};
} // namespace OHOS::Ace

View File

@ -121,4 +121,22 @@ int64_t DataProviderManagerStandard::GetMovingPhotoDateModified(const std::strin
CHECK_NULL_RETURN(helper_, -1);
return helper_->GetMovingPhotoDateModified(uri);
}
int64_t DataProviderManagerStandard::GetMovingPhotoCoverPosition(const std::string& columnName,
const std::string& value,
std::vector<std::string>& columns)
{
InitHelper();
std::shared_lock lock(helperMutex_);
CHECK_NULL_RETURN(helper_, -1);
return helper_->GetMovingPhotoCoverPosition(columnName, value, columns);
}
std::string DataProviderManagerStandard::GetMovingPhotoImagePath(const std::string& uri)
{
InitHelper();
std::shared_lock lock(helperMutex_);
CHECK_NULL_RETURN(helper_, "");
return helper_->GetMovingPhotoImagePath(uri);
}
} // namespace OHOS::Ace

View File

@ -108,6 +108,9 @@ public:
int32_t ReadMovingPhotoVideo(const std::string &uri);
std::string GetMovingPhotoImageUri(const std::string& uri);
int64_t GetMovingPhotoDateModified(const std::string& uri);
int64_t GetMovingPhotoCoverPosition(const std::string& columnName, const std::string& value,
std::vector<std::string>& columns);
std::string GetMovingPhotoImagePath(const std::string& uri);
private:
void InitHelper();

View File

@ -20,7 +20,7 @@
#include "image_analyzer_adapter.h"
namespace OHOS::Ace {
class ImageAnalyzerAdapterImpl : public ImageAnalyzerAdapter {
class ACE_FORCE_EXPORT ImageAnalyzerAdapterImpl : public ImageAnalyzerAdapter {
public:
ImageAnalyzerAdapterImpl();
~ImageAnalyzerAdapterImpl() override;

View File

@ -29,8 +29,12 @@ public:
}
void BuildNodeFunc(void* pixelMap, void* config, ImageAnalyzerInnerConfig* uiConfig,
void** overlayData) override {}
void BuildNodeFunc(std::string uri, void* pixelMap, int frameTimestamp, void* config,
ImageAnalyzerInnerConfig* uiConfig, void** overlayData) override {}
void UpdateImage(void** overlayData, void* pixelMap, void* config,
ImageAnalyzerInnerConfig* uiConfig) override {}
void UpdateImage(void** overlayData, std::string uri, void* pixelMap, int frameTimestamp,
void* config, ImageAnalyzerInnerConfig* uiConfig) override {}
void UpdateConfig(void** overlayData, void* config) override {}
void UpdateInnerConfig(void** overlayData, ImageAnalyzerInnerConfig* config) override {}
void Release(void** overlayData) override {}

View File

@ -24,7 +24,7 @@
namespace OHOS::Ace {
using ImageAnalyzerInstance = std::unique_ptr<ImageAnalyzerInterface, std::function<void (ImageAnalyzerInterface*)>>;
class ImageAnalyzerLoader : public std::enable_shared_from_this<ImageAnalyzerLoader> {
class ACE_FORCE_EXPORT ImageAnalyzerLoader : public std::enable_shared_from_this<ImageAnalyzerLoader> {
public:
static std::shared_ptr<ImageAnalyzerLoader> Load();
~ImageAnalyzerLoader();

View File

@ -25,8 +25,15 @@ namespace OHOS::Ace {
class ImageAnalyzerAdapter;
}
struct ACE_FORCE_EXPORT MovingPhotoAnalyzerInfo {
std::string uri = "";
int64_t frameTimestamp = 0;
float contentWidth = 0.0f;
float contentHeight = 0.0f;
};
namespace OHOS::Ace {
class ImageAnalyzerManager : public AceType {
class ACE_FORCE_EXPORT ImageAnalyzerManager : public AceType {
DECLARE_ACE_TYPE(ImageAnalyzerManager, AceType);
public:
ImageAnalyzerManager(const RefPtr<NG::FrameNode>& frameNode, ImageAnalyzerHolder holder);
@ -37,7 +44,9 @@ public:
bool IsSupportImageAnalyzerFeature();
void CreateAnalyzerOverlay(const RefPtr<OHOS::Ace::PixelMap>& pixelMap, const NG::OffsetF& offset = { 0.0f, 0.0f });
void CreateMovingPhotoAnalyzerOverlay(const RefPtr<OHOS::Ace::PixelMap>& pixelMap, MovingPhotoAnalyzerInfo info);
void UpdateAnalyzerOverlay(const RefPtr<OHOS::Ace::PixelMap>& pixelMap, const NG::OffsetF& offset = { 0.0f, 0.0f });
void UpdateMovingPhotoAnalyzerOverlay(const RefPtr<OHOS::Ace::PixelMap>& pixelMap, MovingPhotoAnalyzerInfo info);
void UpdateAnalyzerOverlayLayout();
void UpdateAnalyzerUIConfig(const RefPtr<NG::GeometryNode>& geometryNode, const PixelMapInfo& info = {});
void DestroyAnalyzerOverlay();
@ -53,6 +62,7 @@ public:
void UpdateAIButtonConfig(AIButtonConfig config);
void UpdateOverlayActiveStatus(bool status);
void SetNotifySelectedCallback(OnNotifySelectedStatusCallback&& callback);
void SetOnCanPlayCallback(OnCanPlayCallback&& callback);
private:
bool UpdateVideoConfig(const PixelMapInfo& info);

View File

@ -22,15 +22,19 @@
namespace OHOS::Ace {
class ACE_EXPORT ImageAnalyzerMgr final : public ImageAnalyzerInterface {
class ACE_FORCE_EXPORT ImageAnalyzerMgr final : public ImageAnalyzerInterface {
public:
static ImageAnalyzerMgr& GetInstance();
bool IsImageAnalyzerSupported() override;
void BuildNodeFunc(void* pixelMap, void* config,
ImageAnalyzerInnerConfig* uiConfig, void** overlayData) override;
void BuildNodeFunc(std::string uri, void* pixelMap, int frameTimestamp, void* config,
ImageAnalyzerInnerConfig* uiConfig, void** overlayData) override;
void UpdateImage(void** overlayData, void* pixelMap, void* config,
ImageAnalyzerInnerConfig* uiConfig) override;
void UpdateImage(void** overlayData, std::string uri, void* pixelMap, int frameTimestamp,
void* config, ImageAnalyzerInnerConfig* uiConfig) override;
void UpdateConfig(void** overlayData, void* config) override;
void UpdateInnerConfig(void** overlayData, ImageAnalyzerInnerConfig* config) override;
void Release(void** overlayData) override;

View File

@ -38,6 +38,7 @@ enum class ImageAnalyzerState;
using OnAnalyzedCallback = std::optional<std::function<void(ImageAnalyzerState)>>;
using OnTextSelectedCallback = std::function<void()>;
using OnNotifySelectedStatusCallback = std::function<void(bool)>;
using OnCanPlayCallback = std::function<void(bool)>;
enum class ImageAnalyzerType {
SUBJECT = 0,
@ -52,6 +53,7 @@ enum class ImageAnalyzerHolder {
VIDEO_DEFAULT,
WEB,
OTHERS,
MOVINGPHOTO,
};
enum class ImageAnalyzerState {
@ -108,6 +110,7 @@ struct ImageAnalyzerInnerConfig {
OHOS::Ace::TouchInfo touchInfo;
OnNotifySelectedStatusCallback onNotifySelectedStatus = nullptr;
bool createAIEngine = false;
OnCanPlayCallback onCanPlay = nullptr;
void UpdateFromInfo(const PixelMapInfo& info)
{

View File

@ -27,8 +27,12 @@ public:
virtual bool IsImageAnalyzerSupported() = 0;
virtual void BuildNodeFunc(
void* pixelMap, void* config, ImageAnalyzerInnerConfig* uiConfig, void** overlayData) {};
virtual void BuildNodeFunc(std::string uri, void* pixelMap, int frameTimestamp, void* config,
ImageAnalyzerInnerConfig* uiConfig, void** overlayData) {};
virtual void UpdateImage(
void** overlayData, void* pixelMap, void* config, ImageAnalyzerInnerConfig* uiConfig) {};
virtual void UpdateImage(void** overlayData, std::string uri, void* pixelMap, int frameTimestamp,
void* config, ImageAnalyzerInnerConfig* uiConfig) {};
virtual void UpdateConfig(void** overlayData, void* config) {};
virtual void UpdateInnerConfig(void** overlayData, ImageAnalyzerInnerConfig* config) = 0;
virtual void Release(void** overlayData) = 0;

View File

@ -26,4 +26,9 @@ RefPtr<PixelMap> PixelMap::DecodeTlv(std::vector<uint8_t>& buff)
{
return AceType::MakeRefPtr<MockPixelMap>();
}
RefPtr<PixelMap> PixelMap::CreatePixelMapFromDataAbility(void* /*rawPtr*/)
{
return AceType::MakeRefPtr<MockPixelMap>();
}
} // namespace OHOS::Ace

View File

@ -47,10 +47,20 @@ void ImageAnalyzerManager::CreateAnalyzerOverlay(const RefPtr<OHOS::Ace::PixelMa
{
}
void ImageAnalyzerManager::CreateMovingPhotoAnalyzerOverlay(const RefPtr<OHOS::Ace::PixelMap>& pixelMap,
MovingPhotoAnalyzerInfo info)
{
}
void ImageAnalyzerManager::UpdateAnalyzerOverlay(const RefPtr<OHOS::Ace::PixelMap>& pixelMap, const NG::OffsetF& offset)
{
}
void ImageAnalyzerManager::UpdateMovingPhotoAnalyzerOverlay(const RefPtr<OHOS::Ace::PixelMap>& pixelMap,
MovingPhotoAnalyzerInfo info)
{
}
void ImageAnalyzerManager::DestroyAnalyzerOverlay()
{
}
@ -107,4 +117,10 @@ void ImageAnalyzerManager::SetNotifySelectedCallback(OnNotifySelectedStatusCallb
{
analyzerUIConfig_.onNotifySelectedStatus = std::move(callback);
}
void ImageAnalyzerManager::SetOnCanPlayCallback(
OnCanPlayCallback&& onCanPlay)
{
analyzerUIConfig_.onCanPlay = std::move(onCanPlay);
}
} // namespace OHOS::Ace

View File

@ -16,6 +16,7 @@
#define NAPI_VERSION 8
#include "core/common/ai/image_analyzer_mgr.h"
namespace OHOS::Ace {
ImageAnalyzerMgr& ImageAnalyzerMgr::GetInstance()
{
@ -33,10 +34,18 @@ void ImageAnalyzerMgr::BuildNodeFunc(
void* pixelMap, void* config, ImageAnalyzerInnerConfig* uiConfig, void** overlayData)
{
}
void ImageAnalyzerMgr::BuildNodeFunc(std::string uri, void* pixelMap, int frameTimestamp,
void* config, ImageAnalyzerInnerConfig* uiConfig, void** overlayData)
{
}
void ImageAnalyzerMgr::UpdateImage(
void** overlayData, void* pixelMap, void* config, ImageAnalyzerInnerConfig* uiConfig)
{
}
void ImageAnalyzerMgr::UpdateImage(void** overlayData, std::string uri, void* pixelMap,
int frameTimestamp, void* config, ImageAnalyzerInnerConfig* uiConfig)
{
}
void ImageAnalyzerMgr::UpdateConfig(void** overlayData, void* config)
{
}

View File

@ -23,7 +23,10 @@
#include "test/mock/core/render/mock_media_player.h"
#include "test/mock/core/render/mock_render_context.h"
#include "test/mock/core/render/mock_render_surface.h"
#include "test/mock/core/common/mock_image_analyzer_manager.h"
#include "test/mock/base/mock_pixel_map.h"
#include "base/image/pixel_map.h"
#include "base/geometry/ng/size_t.h"
#include "base/json/json_util.h"
#include "base/memory/ace_type.h"