Forum Xamarin Xamarin.Forms

Byte[] being converted to stream not displaying image - Image data was invalid: Xamarin.Forms.Stream

LiqwidLiqwid Member ✭✭

I am trying to display images that my app gets as Stream objects. For example:

        private void DoWork(Item item, Stream image)
            // WORKING, until I leave and come back to the page. The stream has been disposed by then.
            item.Image = ImageSource.FromStream( () => image );

This works fine until I navigate away from the page and back. The stream will have been disposed of and I get an exception.

After reading some other posts (, I tried the following:

        private void DoWork( Item item, Stream image)
            // NOT WORKING
            MemoryStream memoryStream = new MemoryStream();
            image.CopyTo( memoryStream );
            memoryStream.Position = 0;

            item.Image = ImageSource.FromStream( () => new MemoryStream( memoryStream.ToArray() ) );

The intent was to convert my source stream to a byte[] and thus create a new Stream to bind to the image each time the page is created. This does not work and give me the following error:

06-06 16:04:07.291 D/skia    (11394): --- Failed to create image decoder with message 'unimplemented'
[0:] ImageLoaderSourceHandler: Image data was invalid: Xamarin.Forms.StreamImageSource

I am using the latest version of Xamarin( Please help me figure out why when I create my own Stream from a byte[] it fails or how I can overcome the stream being disposed of.
I am really at a loss here.



  • LucasZhangLucasZhang Member, Xamarin Team Xamurai
    edited June 2019
    Image image = new Image();
    image.Source = ImageSource.FromStream(() => new MemoryStream(imageAsBytes));
  • LiqwidLiqwid Member ✭✭

    Thanks for your response @LucasZhang.

    Sadly, that is exactly what I am doing above. The item.Image that I am assigning to is actually of type ImageSource so my code is doing what yours does too.

    The error message mentions Image data was invalid. Is that because I am creating my byte array wrong? I am creating it like the following:

                        MemoryStream memoryStream = new MemoryStream();
                        image.CopyTo( memoryStream );
                        var imageAsBytes = memoryStream.ToArray()
  • AravindakumarAravindakumar Member ✭✭
    edited June 2019

    Hi @Liqwid

    Use below code,

        ImageSource retSource = null;
                if (value != null)
                    byte[] imageAsBytes = System.Convert.FromBase64String(value.ToString());
                    //byte[] imageAsBytes = value as byte[];
                    retSource = ImageSource.FromStream(() => new MemoryStream(imageAsBytes));
                    return retSource;
                    return "NoProfile.png";

    retsource is used as source for image.


  • MilindRajMilindRaj USMember ✭✭
    edited May 30

    I am storing user profile photo in a sql server database as varbinary(MAX). I am using WebAPI as follows to upload the photo.

    public static async Task<bool> UploadPhotoToDB(long userId, MultipartFormDataContent content)
            var client = new HttpClient();
            var uri = "" + userId.ToString();
            client.DefaultRequestHeaders.Add("APIKey", APIKey);
            HttpResponseMessage response = await client.PostAsync(uri, content);
            return response.IsSuccessStatusCode;

    The upload works seemingly fine. However, when I download the image, it fails to display. Here is the code.

    public static async Task<MemoryStream> DownloadUserPhoto(long userId)
            var uri = "" + userId;
            HttpClient client = GetClient(uri, out HttpRequestMessage request);
            var response = await client.SendAsync(request);
            byte[] result = await response.Content.ReadAsByteArrayAsync();
            if (result != null)
                return new MemoryStream(result);
                return null;

    And in the view model,

    private async void DownloadPhotoFromDB(long userId)
            MemoryStream stream =  await ApiServices.DownloadUserPhoto(userId);
            Photo = ImageSource.FromStream(() => stream);

    I am more inclined to now store the image in a folder on the server rather than the database and retrieve it from there. However, that exposes the images to anyone who has access to the URL. Is there a way to make the image folder accessible only to the Web API?

Sign In or Register to comment.