【问题标题】:Xamarin Forms Resize image width to fill stacklayout without top and bottom clippingXamarin Forms 调整图像宽度以填充堆栈布局而无需顶部和底部剪辑
【发布时间】:2020-10-08 23:57:27
【问题描述】:

这是我当前的代码:

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="WPapp.Views.Post">
    <ContentPage.Content>
        <ScrollView>
            <StackLayout Margin="10"
                         HorizontalOptions="Center"
                         VerticalOptions="FillAndExpand"
                         x:Name="PostContainer">
                <Image x:Name="FeaturedImage"
                       HorizontalOptions="Center"/>
                <Label x:Name="Title"
                       FontSize="Title"
                       FontAttributes="Bold"
                       Margin="0, 20, 0, 10"/>
                <Label x:Name="PostMeta"
                       FontSize="Caption"
                       FontAttributes="None"
                       Margin="0, 0, 0, 0"/>
            </StackLayout>
        </ScrollView>
    </ContentPage.Content>
</ContentPage>

Image image = new Image();
image.Source = imageSource;
image.Aspect = Aspect.AspectFill;
PostContainer.Children.Add(image);

这是图片:

这是结果:

图像正在按预期水平填充。

问题是,图像被垂直裁剪。如何防止图像被剪裁以及如何在不拉伸的情况下显示完整图像?


如下面答案所示,为了调整图片的大小,使宽度与 StackLayout Container 的最大宽度匹配而不进行裁剪,我需要设置图片的 HeightRequest。

我正在从 WordPress 网站检索帖子。为了解析来自 Wordpress REST API 的 JSON 响应,我使用了 WordpressPCL 包。为了解析我从 WordpressPCL 获得的 HTML 输出,通过 ID 方法获取帖子内容,我正在使用 HTML Agility Pack。

使用 HTML Agility Pack,我能够获取 Wordpress 媒体 ID,然后使用此 ID 查询 Wordpress API 并使用 WordpressPCL 包获取原始图像的宽度和高度以及标题文本。

根据图像的尺寸,我计算了纵横比。使用纵横比,我可以通过将纵横比乘以屏幕的总宽度减去 20 来计算图像的新高度。20 是 StackLayout 的左边距 + 右边距,它是图像的父级。

所有图像现在都是全宽以适合父容器的宽度并且没有被剪裁(100% 高度)。

代码如下(不包括负责解析Wordpress帖子其余内容的代码):

Uri imageSource = new Uri(figure.GetAttributeValue("src", "").ToString());
Int32.TryParse(figure.GetAttributeValue("data-attachment-id", "").ToString(), out int mediaID);
string caption = null;
double aspectRatio = 0;
Task.Run(() =>
{
    Constants wpsite = new Constants();
    var client = new WordPressClient(wpsite.resturl);
    var caption_task = client.Media.GetByID(mediaID);
    caption_task.Wait();
    caption = caption_task.Result.Caption.Rendered;
    double height = caption_task.Result.MediaDetails.Height;
    double width = caption_task.Result.MediaDetails.Width;
    aspectRatio = height / width;
    var htmlCaption = new HtmlDocument();
    htmlCaption.LoadHtml(caption);
    caption = WebUtility.HtmlDecode(htmlCaption.DocumentNode.InnerText);
}).Wait();

Image image = new Image();
image.Source = imageSource;
image.Aspect = Aspect.AspectFit;
double maxWidth = Application.Current.MainPage.Width - 20;
double imageHeight = aspectRatio * maxWidth;
image.HeightRequest = imageHeight;

Label imageCaption = new Label();
imageCaption.Text = caption;
imageCaption.HorizontalTextAlignment = TextAlignment.Center;
imageCaption.FontSize = 12;
imageCaption.Margin = new Thickness(0, 0, 0, 10);

PostContainer.Children.Add(image);
PostContainer.Children.Add(imageCaption);

这是输出:

【问题讨论】:

  • 你需要在图片上设置一个HeightRequest值
  • image.source 设置为该图像的 Uri,并且它正在缩小,因此图像宽度与 StackLayout 容器的宽度相匹配。问题是,图像被垂直裁剪。我应该将 HeightRequest 设置为什么?请详细说明。
  • 图片的实际高度
  • 但是原图的实际高度不会更大吗?它正在缩小,因此宽度与 PostContainer 的宽度相匹配。这不会垂直拉伸图像吗?
  • 然后计算适当的缩放高度。您也可以尝试在图像容器上设置垂直布局选项

标签: c# image xamarin.forms image-resizing aspect-ratio


【解决方案1】:

试试这个。它按预期对我有用。

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="PGCubes.Main.Posts">
    <ScrollView>
        <StackLayout Margin="10"
                         HorizontalOptions="Center"
                         VerticalOptions="FillAndExpand"
                         x:Name="PostContainer">
            <Image x:Name="FeaturedImage"
                       HorizontalOptions="Center"/>
            <Label x:Name="Title"
                       FontSize="Title"
                       FontAttributes="Bold"
                       Margin="0, 20, 0, 10"/>
            <Label x:Name="PostMeta"
                       FontSize="Caption"
                       FontAttributes="None"
                       Margin="0, 0, 0, 0"/>
        </StackLayout>
    </ScrollView>
</ContentPage>

背后的代码:

public partial class Posts : ContentPage
    {
        public Posts()
        {
            InitializeComponent();


            Title.Text = "Aims of this Mission";
            PostMeta.Text = "Lorem Ipsum is simply dummy text of " +
                "the printing and typesetting industry. Lorem Ipsum has been " +
                "the industry's standard dummy text ever since the 1500s, when " +
                "an unknown printer took a galley of type and scrambled it to " +
                "make a type specimen book. It has survived not only five centuries" +
                ", but also the leap into electronic typesetting, remaining essentially " +
                "unchanged. It was popularised in the 1960s with the release of Letraset " +
                "sheets containing Lorem Ipsum passages, and more recently with desktop " +
                "publishing software like Aldus PageMaker including versions of Lorem Ipsum.";

            Image image = new Image();
            image.HeightRequest = 640;
            image.Source = "https://i.stack.imgur.com/r5pdVl.png";
            image.Aspect = Aspect.AspectFit;
            PostContainer.Children.Add(image);

        }
    }

我的三星 A30S 的输出

【讨论】:

  • 这仅适用于 1 张图片,但适用于所有图片。这可以通过获取每个图像的尺寸并将 heightrequest 设置为每个图像的高度来完成。如何从 URL 中获取图像的尺寸?
  • 相信这个链接会对你有所帮助...stackoverflow.com/questions/30054517/…
  • 很遗憾,Xamarin.Forms 不支持 System.Drawing.Image,还有其他方法可以从图像 URL 中获取高度吗?
  • 我设法完成了这项工作,我必须通过从服务器获取每个图像的尺寸来计算纵横比。然后使用计算出的宽高比和宽度计算 HeightRequest,即 Application.Current.MainPage.Width - (PostContainerMarginLeft + PostContainerMarginRight )
  • 很高兴听到这个消息。如果您发布代码将会很有帮助..
猜你喜欢
  • 2021-11-02
  • 1970-01-01
  • 2018-05-21
  • 1970-01-01
  • 1970-01-01
  • 2022-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多