Monday, July 21, 2014

Walk-through for creating a ValueConverter from byte[] to ImageSource

This is a walk-through for how to create a ValueConverter that you can use in code or in Xaml to convert an image stored in an array of bytes (byte[]) to an ImageSource-object and how to bind it.

This comes in handy when you store images in a SQLite database and want to display them in a Xamarin.Forms application.

Prereqs

  • You have a Xamarin Mobile App project
  • You have an image in a byte array

The post is nothing fancy, just the whole thing gathered in one post, instead of four other pieces.

Create the converter

In the core project (main project or what ever you call it), create a folder called Converters and add a class called ByteArrayToImageSourceConverter. Copy the code below into that file

using System;
using System.Globalization;
using System.IO;
using Xamarin.Forms;

namespace YourApp.Converters
{
    public class ByteArrayToImageSourceConverter : IValueConverter
    { 
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null)
            {
                return null;
            }

            byte[] bytes = value as byte[];
            return ImageSource.FromStream(() => new MemoryStream(bytes));
        }

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


You need a ViewModel with an image property

Add a model of your liking. One of the properties must be a byte array so that you'd have something to bind to. The code below is just a sample model. Since we implement INotifyPropertyChanged, the image will automatically update if you set the Image property on the ViewModel.

using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace YourApp.ViewModels
{
    public class YourViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public string Notes { get; set; }

        private byte[] _image;
        public byte[] Image 
        { 
            get 
            { 
                return _image; 
            } 
            set 
            { 
                _image = value; 
                OnPropertyChanged(); 
            } 
        }

        void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

Use the converter in Xaml

There are a couple of hoops that you need to get through to use this converter in Xaml. 
  • You need to import the namespace (xmlns:local="clr....)
  • You must reference the converter as a static resource ()
  • In the binding for the image, declare that you want the converter to be used (Converter={StaticResource bic}})

xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:YourApp.Converters;assembly=YourApp"
                       x:Class="YourApp.Views.YourPage"
             Title="A cool title"
             Icon="new44.png">

  <ContentPage.Resources>
    <ResourceDictionary>
      <local:ByteArrayToImageSourceConverter x:Key="bic" />
    </ResourceDictionary>
  </ContentPage.Resources>
 
  <StackLayout VerticalOptions="FillAndExpand">
    <Image x:Name="image" Source="{Binding Image, Converter={StaticResource bic}}" />

  </StackLayout>
</ContentPage>

Resource on xaml namespaces

Use the converter in code

You can also create the binding in code. In the constructor of your page, after InitalizeComponent, define the binding like the example below.

 var binding = new Binding("Image", BindingMode.Default, new ByteArrayToImageSourceConverter());
            image.SetBinding(Image.SourceProperty, binding);

That's about it. Nothing fancy, just all in one place if needed.

7 comments:

  1. How we can call Dispose on MemoryStream? I tried to make use of using statement, but, If we call dispose, then we face "Cannot access a closed Stream." error.

    ReplyDelete
    Replies
    1. Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.. I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a .Net developer learn from Dot Net Training in Chennai. or learn thru Dot Net Training in Chennai. Nowadays Dot Net has tons of job opportunities on various vertical industry.
      or Javascript Training in Chennai. Nowadays JavaScript has tons of job opportunities on various vertical industry.

      Delete
  2. You will definitely find some useful info in this article about essay writing tips and tricks. So check it out as soon as possible

    ReplyDelete
  3. EduBirdie's terms and conditions have a lot of insights. If you you're going to order an essay at this website, read them carefully. The key things to remember here is that it's possible to place a refund request during 3 days after the paper was uploaded, or money will be released automatically; they reserve the right to give some percent of money to a writer if they see that your actions have no strong reasons. More info about the company can be found in our edubirdie review. If you are looking for information about “edubirdie write”, welcome to Scamfighter!

    ReplyDelete
  4. If you do not know what led you to pursue pharmacy, or you find that studying pharmaceuticals is not that captivating, you should stop here. Pharmacy school, along with post-graduate courses, is a laborious path, and if you are applying to this program just to please your parents or to deal with some external pressure, you will find yourself unhappy later down the road. Make sure your choice to attend is your own and not the decision of someone else. Hopefully, after reading this far, you now acknowledge the upsides and the downsides of this profession. Click pharmacy personal statement for detailed information.

    ReplyDelete
  5. Your post help me in completin a client project. Thank you

    ReplyDelete