解决图片、视频分辨率不一致场景自适应拉伸

Signed-off-by: jiangqiushi <jiangqiushi@huawei.com>
This commit is contained in:
jiangqiushi 2024-05-21 09:50:36 +08:00
parent f9db9fe409
commit 2bb16d4eca
5 changed files with 78 additions and 31 deletions

View File

@ -135,6 +135,7 @@
OHOS::Ace::NG::FlexLayoutAlgorithm::*;
OHOS::Ace::NG::FrameNode::*;
OHOS::Ace::NG::GestureEventHub::*;
OHOS::Ace::NG::ImageLoadingContext::*;
OHOS::Ace::NG::ImagePattern::*;
OHOS::Ace::NG::LayoutProperty::*;
OHOS::Ace::NG::LayoutWrapper::*;

View File

@ -23,6 +23,7 @@
#include "base/log/ace_trace.h"
#include "base/utils/system_properties.h"
#include "core/components_ng/pattern/image/image_layout_property.h"
#include "core/components_ng/pattern/image/image_pattern.h"
#include "core/components_ng/property/property.h"
#include "core/pipeline_ng/pipeline_context.h"
@ -474,18 +475,20 @@ bool MovingPhotoPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& d
return false;
}
SizeF MovingPhotoPattern::CalculateFitContain(const SizeF& videoSize, const SizeF& layoutSize)
SizeF MovingPhotoPattern::CalculateFitContain(const SizeF& rawSize, const SizeF& layoutSize)
{
double layoutRatio = NearZero(layoutSize.Height()) ? 0.0 : layoutSize.Width() / layoutSize.Height();
double sourceRatio = NearZero(videoSize.Height()) ? layoutRatio : videoSize.Width() / videoSize.Height();
if (NearZero(layoutRatio) || NearZero(sourceRatio)) {
if (NearZero(rawSize.Height()) || NearZero(rawSize.Width()) || NearZero(layoutSize.Height())) {
return layoutSize;
}
double sourceRatio = rawSize.Width() / rawSize.Height();
double layoutRatio = layoutSize.Width() / layoutSize.Height();
if (sourceRatio < layoutRatio) {
return { static_cast<float>(sourceRatio) * layoutSize.Height(), layoutSize.Height() };
float ratio = layoutSize.Height() / rawSize.Height();
return { rawSize.Width() * ratio, layoutSize.Height() };
} else {
float ratio = layoutSize.Width() / rawSize.Width();
return { layoutSize.Width(), rawSize.Height() * ratio };
}
return { layoutSize.Width(), static_cast<float>(layoutSize.Width() / sourceRatio) };
}
SizeF MovingPhotoPattern::CalculateFitFill(const SizeF& layoutSize)
@ -493,31 +496,64 @@ SizeF MovingPhotoPattern::CalculateFitFill(const SizeF& layoutSize)
return layoutSize;
}
SizeF MovingPhotoPattern::CalculateFitCover(const SizeF& videoSize, const SizeF& layoutSize)
SizeF MovingPhotoPattern::CalculateFitCover(const SizeF& rawSize, const SizeF& layoutSize)
{
double layoutRatio = NearZero(layoutSize.Height()) ? 0.0 : layoutSize.Width() / layoutSize.Height();
double sourceRatio = NearZero(videoSize.Height()) ? layoutRatio : videoSize.Width() / videoSize.Height();
if (NearZero(layoutRatio) || NearZero(sourceRatio)) {
if (NearZero(rawSize.Height()) || NearZero(rawSize.Width()) || NearZero(layoutSize.Height())) {
return layoutSize;
}
double sourceRatio = rawSize.Width() / rawSize.Height();
double layoutRatio = layoutSize.Width() / layoutSize.Height();
float ratio = 1.0;
if (sourceRatio < layoutRatio) {
return { layoutSize.Width(), static_cast<float>(layoutSize.Width() / sourceRatio) };
ratio = static_cast<float>(layoutSize.Width() / rawSize.Width());
} else {
ratio = static_cast<float>(layoutSize.Height() / rawSize.Height());
}
return { static_cast<float>(layoutSize.Height() * sourceRatio), layoutSize.Height() };
return { rawSize.Width() * ratio, rawSize.Height() * ratio};
}
SizeF MovingPhotoPattern::CalculateFitNone(const SizeF& videoSize)
SizeF MovingPhotoPattern::CalculateFitNone(const SizeF& rawSize)
{
return videoSize;
return rawSize;
}
SizeF MovingPhotoPattern::CalculateFitScaleDown(const SizeF& videoSize, const SizeF& layoutSize)
SizeF MovingPhotoPattern::CalculateFitScaleDown(const SizeF& rawSize, const SizeF& layoutSize)
{
if (layoutSize.Width() > videoSize.Width()) {
return CalculateFitNone(videoSize);
if ((rawSize.Width() <= layoutSize.Width()) && (rawSize.Height() <= layoutSize.Height())) {
return CalculateFitNone(rawSize);
} else {
return CalculateFitContain(rawSize, layoutSize);
}
return CalculateFitContain(videoSize, layoutSize);
}
SizeF MovingPhotoPattern::CalculateFitAuto(const SizeF& rawSize, const SizeF& layoutSize)
{
if (NearZero(rawSize.Width()) || NearZero(rawSize.Height())) {
return layoutSize;
}
if ((rawSize.Width() <= layoutSize.Width()) && (rawSize.Height() <= layoutSize.Height())) {
double widthRatio = layoutSize.Width() / rawSize.Width();
double heightRatio = layoutSize.Height() / rawSize.Height();
float ratio = static_cast<float>(std::min(widthRatio, heightRatio));
return { rawSize.Width() * ratio, rawSize.Height() * ratio };
} else if ((rawSize.Width() > layoutSize.Width()) && (rawSize.Height() <= layoutSize.Height())) {
return CalculateFitContain(rawSize, layoutSize);
} else {
return CalculateFitCover(rawSize, layoutSize);
}
}
SizeF MovingPhotoPattern::GetRawImageSize()
{
auto host = GetHost();
CHECK_NULL_RETURN(host, SizeF(-1, -1));
auto movingPhoto = AceType::DynamicCast<MovingPhotoNode>(host);
CHECK_NULL_RETURN(movingPhoto, SizeF(-1, -1));
auto image = AceType::DynamicCast<FrameNode>(movingPhoto->GetImage());
CHECK_NULL_RETURN(image, SizeF(-1, -1));
auto imagePattern = image->GetPattern<ImagePattern>();
CHECK_NULL_RETURN(image, SizeF(-1, -1));
return imagePattern->GetRawImageSize();
}
SizeF MovingPhotoPattern::MeasureContentLayout(const SizeF& layoutSize, const RefPtr<MovingPhotoLayoutProperty>& layoutProperty)
@ -526,27 +562,27 @@ SizeF MovingPhotoPattern::MeasureContentLayout(const SizeF& layoutSize, const Re
return layoutSize;
}
auto videoSize = layoutProperty->GetVideoSizeValue(SizeF(0, 0));
auto rawImageSize = GetRawImageSize();
auto imageFit = layoutProperty->GetObjectFitValue(ImageFit::COVER);
SizeF contentSize = { 0.0, 0.0 };
switch (imageFit) {
case ImageFit::CONTAIN:
contentSize = CalculateFitContain(videoSize, layoutSize);
contentSize = CalculateFitContain(rawImageSize, layoutSize);
break;
case ImageFit::FILL:
contentSize = CalculateFitFill(layoutSize);
break;
case ImageFit::COVER:
contentSize = CalculateFitCover(videoSize, layoutSize);
contentSize = CalculateFitCover(rawImageSize, layoutSize);
break;
case ImageFit::NONE:
contentSize = CalculateFitNone(videoSize);
contentSize = CalculateFitNone(rawImageSize);
break;
case ImageFit::SCALE_DOWN:
contentSize = CalculateFitScaleDown(videoSize, layoutSize);
contentSize = CalculateFitScaleDown(rawImageSize, layoutSize);
break;
default:
contentSize = CalculateFitContain(videoSize, layoutSize);
contentSize = CalculateFitAuto(rawImageSize, layoutSize);
}
return contentSize;

View File

@ -93,12 +93,14 @@ private:
void UpdateImageNode();
void UpdateVideoNode();
SizeF CalculateFitContain(const SizeF& videoSize, const SizeF& layoutSize);
SizeF CalculateFitContain(const SizeF& rawSize, const SizeF& layoutSize);
SizeF CalculateFitFill(const SizeF& layoutSize);
SizeF CalculateFitCover(const SizeF& videoSize, const SizeF& layoutSize);
SizeF CalculateFitNone(const SizeF& videoSize);
SizeF CalculateFitScaleDown(const SizeF& videoSize, const SizeF& layoutSize);
SizeF CalculateFitCover(const SizeF& rawSize, const SizeF& layoutSize);
SizeF CalculateFitNone(const SizeF& rawSize);
SizeF CalculateFitScaleDown(const SizeF& rawSize, const SizeF& layoutSize);
SizeF CalculateFitAuto(const SizeF& rawSize, const SizeF& layoutSize);
SizeF MeasureContentLayout(const SizeF& layoutSize, const RefPtr<MovingPhotoLayoutProperty>& layoutProperty);
SizeF GetRawImageSize();
void PrepareMediaPlayer();
void ResetMediaPlayer();

View File

@ -30,7 +30,7 @@ using PendingMakeCanvasImageTask = std::function<void()>;
// [ImageLoadingContext] do two things:
// 1. Provide interfaces for who owns it, notify it's owner when loading events come.
// 2. Drive [ImageObject] to load and make [CanvasImage].
class ImageLoadingContext : public AceType {
class ACE_FORCE_EXPORT ImageLoadingContext : public AceType {
DECLARE_ACE_TYPE(ImageLoadingContext, AceType);
public:

View File

@ -311,6 +311,14 @@ public:
void SetOnProgressCallback(std::function<void(const uint32_t& dlNow, const uint32_t& dlTotal)>&& onProgress);
SizeF GetRawImageSize()
{
if (!loadingCtx_) {
return SizeF(-1.0, -1.0);
}
return loadingCtx_->GetImageSize();
}
protected:
void RegisterWindowStateChangedCallback();
void UnregisterWindowStateChangedCallback();