Persisting an image

Windows Phone From Scratch

In our Full Stack program we need to take a snapshot and persist it to isolated storage, for PicturePicture retrieval at a later time.  This posed an interesting question: how do you put an image into a serializable form, yet reconstitute it to be the source for the Image control.

Let’s simplify the problem and strip it down to its essentials.  In this demonstration program we will interact with the UI shown in the figure.

[Click on the image to see full size]

The following controls are shown

  1. A TextBlock acting as a prompt
  2. A TextBox to gather the user’s name
  3. A Picture button to bring up the camera
  4. A Save button to save the user and the picture
  5. A Find button to locate the picture of the person whose name is in the text box

The Save and Find buttons start out disabled, and are enabled only when there is text in the text box.

When you click save, a person object is created and the person’s name and picture are stored to a dictionary (the same state they need to be in for persisting in isolated storage).  When you click find, if the person exists in the dictionary of people, then the person and picture are retrieved.

The Person object represents the name as a string and the image as a byte array,

public class Person
{
    public string FullName { get; set; }
    public byte[] Thumbnail { get; set; }
}

We begin the code section by creating a camera capture task, a dictionary to “persist” the person objects and a byte array to hold the thumbnail pending persistence,

private readonly CameraCaptureTask camera =
    new CameraCaptureTask();
private readonly Dictionary<string, Person> people =
    new Dictionary<string, Person>();
private byte[] thumbnail;

In the constructor we establish the event handlers for the buttons and the event handler for the camera’s asynchronous call back (called when the chooser returns).

public MainPage()
{
    InitializeComponent();
    camera.Completed +=  camera_Completed ;
    TakePicture.Click += ( o, e ) => { camera.Show(); };
    FullName.TextChanged += ( o, e ) =>
    {
        Find.IsEnabled = Save.IsEnabled =
            String.IsNullOrEmpty( FullName.Text ) ? false : true;
    };
    Save.Click += Save_Click;
    Find.Click += Find_Click;
}

Line 4 sets up the callback for the camera task

Line 5 is the event handler for the Picture button, it simply invokes the camera task

Lines 6-10 are the event handler for the TextChanged event in the text box, enabling and disabling our two buttons depending on whether or not there is text in the box.

Lines 11 and 12 set up the event handlers for the buttons.

Camera Completed

The Camera Completed task is responsible for retrieving the picture taken and displaying it to the user. We also take that opportunity to stash the picture into the member variable thumbnail for storage later when we have a Person object to store.

private void camera_Completed( object sender, PhotoResult e )
{
    var _imageBytes = new byte[e.ChosenPhoto.Length];
    e.ChosenPhoto.Read( _imageBytes, 0, _imageBytes.Length );
    e.ChosenPhoto.Seek( 0, SeekOrigin.Begin );

    Picture.Source = PictureDecoder.DecodeJpeg( e.ChosenPhoto );

    thumbnail = _imageBytes;
}

The process of making the image ready for display is to create a byte array of the size of the image as shown on line 3.

On line 4 we read the correct  number of bytes into that byte array and on line 5 we seek sto the start of the array.  We then assign to the Picture (image control) Source property the image created by calling the static method DecodeJpeg on PictureDecoder, passing in the photo as retrieved from the task.

When the Save button is clicked our job is to create a new Person object, populate it with the text from the TextBox and the byteArray we stored in the member variable thumbnail and then store the person into the Dictionary.

void Save_Click( object sender, RoutedEventArgs e )
{
    Person p = new Person()
    {
        FullName = FullName.Text,
        Thumbnail = thumbnail
    };
    Picture.Source = null;
    FullName.Text = "";
    people.Add(p.FullName,p);
}

While we are at it, we set the Picture (the image control) Source property to null, removing the picture from display and blank the text box – good feedback that the person has been saved.

When the Find button is clicked we check to see if the name in the TextBox matches a name in the dictionary.  If not, we show a messageBox that the name was not found.  If so, however, we retrieve that person object from the dictionary.

void Find_Click( object sender, RoutedEventArgs e )
{
    Picture.Source = null;

    if ( !  people.Keys.Contains(FullName.Text) )
    {
        MessageBox.Show(FullName.Text + " not found.");
        return;
    }
    var per = people[FullName.Text];

    if (per.Thumbnail == null)
    {
        Picture.Source = null;
        return;
    }
    byte[] data = per.Thumbnail;
    using (Stream memStream = new MemoryStream( data ))
    {
        WriteableBitmap wbimg =
            PictureDecoder.DecodeJpeg( memStream );
        Picture.Source = wbimg;
    }
}

If the Thumbnail property is null, there is no picture to display and we set the Source property of the Image control to null and return.  Otherwise, we create a local copy of the byte array held by the Person object which we pass into a new MemoryStream.  That memory stream is used to create a WriteableBitMap which is the source for displaying the image.

Share

About Jesse Liberty

Jesse Liberty is a Master Consultant for Falafel Software, and has three decades of experience writing and delivering software projects. He is the author of 2 dozen books and multiple Pluralsight courses, and has been a Technical Evangelist for Telerik and for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS.
This entry was posted in Data, Mini-Tutorial, Patterns & Skills, WindowsPhone and tagged . Bookmark the permalink.

14 Responses to Persisting an image

  1. Hubert says:

    hello!,I love your writing very a lot! proportion we communicate more about your article on AOL?

    I require a specialist in this house to unravel my problem.
    Maybe that is you! Looking forward to peer you.

  2. Superb website you have here but I was wanting to know if
    you knew of any forums that cover the same topics discussed here?
    I’d really love to be a part of group where I can get feed-back from
    other experienced people that share the same interest. If you
    have any suggestions, please let me know. Cheers!

  3. Great post. I wasѕ checking constantly this blog and I am impressed!
    Extremely helpful info specially the last
    part :) I car for suuch info much. I was lookіng ffor this certаin information for a ѵery long
    timе. Thank you aand goodd luck.

  4. Hey I know this is off topic but I was wondering if you knew of any widgets I could add to my blog that automatically tweet my newest twitter updates.
    I’ve been looking for a plug-in like this for quite some time and was hoping maybe
    you would have some experience with something like
    this. Please let me know if you run into anything.
    I truly enjoy reading your blog and I look forward to your
    new updates.

  5. It is actually a great and helpful piece of information.
    I am satisfied that you just shared this useful info with us.
    Please stay us informed like this. Thank you for sharing.

  6. Woah! I’m really enjoying the template/theme of this site.
    It’s simple, yet effective. A lot of times it’s hard to get that “perfect balance” between user friendliness and visual appeal.

    I must say you’ve done a great job with this. In addition, the blog
    loads very quick for me on Chrome. Excellent Blog!

  7. Aaron says:

    Hi! Someone in my Facebook group shared this website with us so I came to look it over.
    I’m definitely enjoying the information. I’m bookmarking and will be tweeting this to my
    followers! Fantastic blog and amazing style and design.

    slots bonuses [Aaron]

  8. Anonymous says:

    Excellent confident analytical vision for the purpose
    of detail and can anticipate troubles just before they will
    happen.

  9. magnificent post, very informative. I wonder why the other
    specialists of this sector don’t realize this. You should proceed your writing. I am confident, you have a huge readers’ base already!

    Here is my weblog :: projektowanie logo program

  10. Marilou says:

    Hello there! Quick question that’s completely off topic. Do you know how to make your site mobile friendly? My weblog looks weird when viewing from my iphone. I’m trying to find a theme or plugin that might be
    able to resolve this issue. If you have any recommendations, please share.
    With thanks!

  11. Pingback: Windows Phone From Scratch – Persisting an image – www.nalli.net

  12. Pingback: Persisting an image | WP7 Developers Links

  13. Ahmad Hesam says:

    ich bedanke mich alle Herzliche menschen so helfreich sind.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>