简体   繁体   中英

Xamarin Forms Resize image width to fill stacklayout without top and bottom clipping

This is the current code I have:

<?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);

This is the image:

图片

This is the result:

结果

The image is being filled horizontally as intended.

The problem is, the image is being clipped vertically. How can I prevent the image from being clipped and how do I display the full image without stretching?


As shown in the answer below, in order to resize the image so the width matches the maximum width of the StackLayout Container without clipping, I needed to set the HeightRequest of the image.

I am retrieving posts from a WordPress Website. To parse the JSON response from the Wordpress REST API, I am using the WordpressPCL package. In order to parse the HTML output that I get from the WordpressPCL get post content by ID method, I am using the HTML Agility Pack.

With the HTML Agility Pack, I was able to get the Wordpress media ID, this ID was then used to query the Wordpress API and get the original image's width and height and caption text with the WordpressPCL package.

From the dimensions of the image, I calculated the aspect ratio. With the aspect ratio, I was able to calculate the new Height of the image by multiplying the aspect ratio with the total width of the screen minus 20. 20 is the left margin + right margin of the StackLayout which is the parent of the image.

All the images are now full width to fit the width of the parent container and are not clipped (100% height).

Code is as below (excluding the code which is responsible for parsing the rest of the content of the Wordpress post):

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);

This is the output:

输出

Try this one. It worked for me as intended.

<?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>

The code behind:

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);

        }
    }

The output from my samsung A30S 在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM