Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make an image auto-resize so the width is 100% and the height adjusted accordingly?

I have the following simple XAML page:

<?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="Test.UserGuides.VPN">
    <ContentPage.Content>
        <ScrollView>
            <StackLayout HorizontalOptions="Center" VerticalOptions="Center" Margin="10,10,10,10">
                <Label Margin="10,10,10,10" Text="How to connect to VPN." HorizontalOptions="Center" />
                <Label Margin="10,10,10,10" Text="If you have a corporate notebook, look for the Cisco AnyConnect application. Either in your start menu, on your desktop, or in your taskbar." />
                <Image x:Name="imgVPN1" Margin="10,10,10,10" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
                <Label Margin="10,10,10,10" Text="Select your region and press the Connect button." />
            </StackLayout>
        </ScrollView>
    </ContentPage.Content>
</ContentPage>

In the constructor, I call a method to load the images:

private void LoadImages()
{
    imgVPN1.Aspect = Aspect.AspectFit;
    ImageSource imagesrc = ImageSource.FromResource("Test.Files.CiscoAnyConnect.PNG");
    imgVPN1.Source = imagesrc;
}

The result looks like this on my (rather large, high DPI) phone:

imgur link 1

Of course, I want the image to automatically expand so it takes up the entire width of the screen. While maintaining the aspect ratio. But how can I achieve this? I've already tried putting the Aspect to "AspectFill", and added

imgVPN1.WidthRequest = Application.Current.MainPage.Width;

To the LoadImages method, but that makes the end result look like this:

imgur link 2

I've been toying around with various HorizontalOptions, VerticalOptions, Aspects, GridView, StackLayouts,... The end result is always either the first or the second screenshot. So how can I achieve what I want here?

like image 934
Matthias Avatar asked Jul 18 '17 20:07

Matthias


People also ask

How do I resize an image automatically?

Answer: Use the CSS max-width Property You can simply use the CSS max-width property to auto-resize a large image so that it can fit into a smaller width <div> container while maintaining its aspect ratio.

How do you make a full width image responsive?

To make an image responsive, you need to give a new value to its width property. Then the height of the image will adjust itself automatically. The important thing to know is that you should always use relative units for the width property like percentage, rather than absolute ones like pixels.


1 Answers

Here is what can be done. XML almost didn't change, I just removed image Layout Options

<ContentPage.Content>
        <ScrollView>
            <StackLayout HorizontalOptions="Center" VerticalOptions="Center" Margin="10,10,10,10">
                <Label Margin="10,10,10,10" Text="How to connect to VPN." HorizontalOptions="Center" />
                <Label Margin="10,10,10,10" Text="If you have a corporate notebook, look for the Cisco AnyConnect application. Either in your start menu, on your desktop, or in your taskbar." />
                <Image x:Name="imgVPN1" Margin="10,10,10,10" />
                <Label Margin="10,10,10,10" Text="Select your region and press the Connect button." />
            </StackLayout>
        </ScrollView>
    </ContentPage.Content>

After implementing everything in relative layout which also was not simple (I have the code if anybody needs it let me know) I found easier way. The key point is that image doesn't scale correctly and occupies too much space in height. But we know the size ratio of this image so we can use it. In the code we need to override OnSizeAllocated because in constructor the width is unknown yet. Then it's easy

protected override void OnSizeAllocated(double width, double height)
{
    base.OnSizeAllocated(width, height);
    imgVPN1.WidthRequest = width;
    imgVPN1.HeightRequest = width / 2.152; //given that image is 411 x 191
}

You could use other width than page with if you want. For example you could use stack layout width to consider margins for more accuracy but this is already tuning. Or you actually could use the image width itself like that

 protected override void OnSizeAllocated(double width, double height)
 {
     base.OnSizeAllocated(width, height);
     double needHeight=imgVPN1.Width / 2.152;
     if (imgVPN1.Height != needHeight)
         imgVPN1.HeightRequest = needHeight;
 }

enter image description here

like image 93
Yuri S Avatar answered Nov 08 '22 21:11

Yuri S