Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin Forms - Image source not working from url

I have updated my Visual Studio from 2017 (15.9.16) to 2019 (16.3.1). Then i opened old (2017) project in 2019 studio, run in Android emulator and have found that all images with url as source are not displayed. I tried different variants, but nothing help.

Then i created blank application for test:
App1 (.Net Standard 2.0) + App1.Android.

MainPage.xaml:

<StackLayout>
    <Label Text="Welcome to Xamarin.Forms!" 
       HorizontalOptions="Center"
       VerticalOptions="CenterAndExpand" />

    <Frame HeightRequest="200" BackgroundColor="#E7E7E7">
        <Image x:Name="myImage" Aspect="Fill" />
        <!--<Image Source="http://lealan.me/Content/images/typist/typist07.jpg" />-->
        <!--<Image>
            <Image.Source>
                <UriImageSource Uri="http://lealan.me/Content/images/typist/typist07.jpg" />
            </Image.Source>
        </Image>-->            
    </Frame>
</StackLayout>

MainPage.xaml.cs:

public MainPage()
{
    InitializeComponent();

    var url = "http://lealan.me/Content/images/typist/typist07.jpg";

    // variant 1 (not worked)
    //this.myImage.Source = ImageSource.FromUri(new Uri(url));

    // variant 2 (not worked)
    //this.myImage.Source = new UriImageSource() { Uri = new Uri(url) };

    // variant 3 (only this variant worked)
    var byteArray = new WebClient().DownloadData(url);
    this.myImage.Source = ImageSource.FromStream(() => new MemoryStream(byteArray));

    // + see others variants in MainPage.xaml
}

Also i tried different "Http Client implementation" in "Advanced Android Options", i even tried granted ALL permissions to android application, but nothing help.
(only variant 3 worked, but it heavy for MVVM binding)

like image 509
Lealan Avatar asked Sep 27 '19 05:09

Lealan


1 Answers

I got this problem before and it have to do with the server not adding the right header.

The best solution i got is to create a Converter that download the image. as your variant 3.

Here is what i did.

    public class ImageSourceConverter : IValueConverter
    {
        static WebClient Client = new WebClient();
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
             if (value == null)
                 return null;

             var byteArray = Client.DownloadData(value.ToString());
             return ImageSource.FromStream(() => new MemoryStream(byteArray));
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }


// And the xaml

<Image Source="{Binding ImageUrl, Converter={StaticResource ImageSourceConverter}}" />
like image 180
Alen.Toma Avatar answered Oct 22 '22 13:10

Alen.Toma