xamarin .NET MAUI图像大小错误

o2g1uqev  于 2023-02-20  发布在  .NET
关注(0)|答案(1)|浏览(229)

当我在. NET MAUI上显示图像时遇到了一个问题,图像的大小总是比实际大(下图中的蓝色部分)。
Screenshot
我的代码如下:

<Grid>
    <ScrollView>
        <VerticalStackLayout>
            <Image Source="https://cdn-5e5150f5f911c807c41ebdc8.closte.com/wp-content/uploads/IoT-development-kit-article-banner-scaled-900x400.jpg"
                    Aspect="AspectFit" BackgroundColor="Blue">
                <Image.Margin>
                    <OnIdiom Phone="10" Tablet="20" Desktop="20"/>
                </Image.Margin>
            </Image>
        </VerticalStackLayout>
    </ScrollView>
</Grid>

有没有办法保持图像的大小与实际大小成比例?

nnt7mjpx

nnt7mjpx1#

我做了些改变:
1.我试着以MVVM的方式使用数据绑定。
1.我试着用平台代码计算图像比率。
下面是我的代码,

    • 对于MainPage.xaml**,不同之处在于我对图像Source和AspectRatio属性使用数据绑定,这将在MainPageVeiwModel中声明。
<Grid>
    <ScrollView>
        <VerticalStackLayout>                          
            <a:AspectImage Source="{Binding ImageUrl}"
                     AspectRatio="{Binding AspectRatio}" Aspect="AspectFit" BackgroundColor="Blue">
                <a:AspectImage.Margin>
                    <OnIdiom Phone="10" Tablet="20" Desktop="20"/>
                </a:AspectImage.Margin>
            </a:AspectImage>
        </VerticalStackLayout>
    </ScrollView>
</Grid>
    • 对于自定义控件AspectImage**,不同之处在于我将AspectRatio更改为Bindable属性,因为我们对该属性使用绑定。
public class AspectImage : Image
{
    public static readonly BindableProperty AspectRatioProperty = BindableProperty.Create("AspectRatio", typeof(double), typeof(AspectRatioContainer), null);

    public double AspectRatio
    {
        get { return (double)GetValue(AspectRatioProperty); }
        set { SetValue(AspectRatioProperty, value); }
    }

    public AspectImage()
    {
        SizeChanged += HandleSizeChanged;
    }

    private void HandleSizeChanged(object sender, EventArgs e)
    {
        if (this.Width > 0 && AspectRatio > 0)
        {
            var desiredHeightRequest = this.Width * AspectRatio;
            if ((int)desiredHeightRequest != (int)HeightRequest)
            {
                this.HeightRequest = (int)desiredHeightRequest;
                InvalidateMeasure();
            }
        }
    }
}
    • 对于MainPageViewModel**,我们为自定义控件添加了AspectRatio和ImageUrl属性,并对AspectRatio进行计数。
public class MainPageViewModel
{
    public string ImageUrl { get; set; }
    public double AspectRatio { get; set; }

    public MainPageViewModel()
    {
        ImageUrl = "https://cdn-5e5150f5f911c807c41ebdc8.closte.com/wp-content/uploads/IoT-development-kit-article-banner-scaled-900x400.jpg";

        AspectRatio = CountAspectRatio(ImageUrl);
    }

    private double CountAspectRatio(string imageUrl)
    {
        var service = new GetImageSizeService();
        Size imageSize = service.GetImageSize(imageUrl);
        return imageSize.Height / imageSize.Width;
    }
}

从MainPageViewModel上面的代码中,我们通过调用平台代码来统计AspectRatio,如果你不熟悉,我先推荐这个教程:How To Write Platform-Specific Code in .NET MAUI.
在Maui注入平台代码(在Xamarin中可以使用DependencyService):
首先,在Project文件夹中创建一个新的分部类,我们将其命名为GetImageSizeService:

public partial class GetImageSizeService
{
    public partial Size GetImageSize(string file);
}

然后在Platforms/iOS文件夹中创建另一个分部类,也称为GetImageSizeService。注意命名空间应与上述文件相同

public partial class GetImageSizeService
{
    public partial Size GetImageSize(string file)
    {
        NSData data = NSData.FromUrl(NSUrl.FromString(file));

        UIImage image = UIImage.LoadFromData(data);
        return new Size((double)image.Size.Width, (double)image.Size.Height);
    }
}

然后在MainPageViewModel中,我们只需要调用这个服务并计算AspectRatio。
============================第一个帖子=========
你添加的链接确实启发了我。如果我正确理解了你的问题,你可以尝试下面的代码,这对我很有效:
创建AspectImage自定义控件,用于设置宽度和高度的纵横比

public class AspectImage : Image
{
    public double AspectRatio { get; set; }

    public AspectImage()
    {
        SizeChanged += HandleSizeChanged;
    }

    private void HandleSizeChanged(object sender, EventArgs e)
    {
        if (this.Width > 0 && AspectRatio > 0)
        {
            var desiredHeightRequest = this.Width * AspectRatio;           
            if ((int)desiredHeightRequest != (int)HeightRequest)
            {
                this.HeightRequest = (int)desiredHeightRequest;
                InvalidateMeasure();
            }
        }
    }
}

对于xaml,使用AspectImage,这里的长宽比似乎是4/9,大约等于0.44

<Grid>
    <ScrollView>
        <VerticalStackLayout>                          
            <a:AspectImage Source="https://cdn-5e5150f5f911c807c41ebdc8.closte.com/wp-content/uploads/IoT-development-kit-article-banner-scaled-900x400.jpg"
                     AspectRatio="0.44" Aspect="AspectFit" BackgroundColor="Blue">
                <a:AspectImage.Margin>
                    <OnIdiom Phone="10" Tablet="20" Desktop="20"/>
                </a:AspectImage.Margin>
            </a:AspectImage>
        </VerticalStackLayout>
    </ScrollView>
</Grid>

希望对你有用。

相关问题