Saving an Image to the Pictures Hub

Something that will also be discussed during the upcoming Windows Phone course, here at U2U, is the cooperation between Silverlight for Windows Phone and XNA.

At the end of my previous blog post, I was left with one more challenge: saving my modified picture to the Pictures Hub. Until shortly I thought that the only way of using the Pictures Hub was through the PhotoChooserTask or the CameraCaptureTask. Luckily I came across the MediaLibrary-class from the XNA-framework, who gives much more possibilities for accessing your pictures.

To start I needed to add a reference to Microsoft.Xna.Framework. This results in an alarming message :


At first I tried to do some experimenting with the MediaLibrary. Let’s start by simply getting the number of pictures I have on the emulator :

ml = new MediaLibrary();
nrOfPics = ml.Pictures.Count;


That works nice. The Medialibrary has several collection I can use, like Pictures, Songs, Genres,…

Next step : lets create a little slideshow-app for iterating through my pictures. I start out with a simple page :

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <RowDefinition Height="523*" />
        <RowDefinition Height="84*" />
    <Image Name="image1" Stretch="Fill" />
    <Grid Grid.Row="1" Name="grid1">
        <Button Content="&gt;&gt;" Grid.Column="1" Name="btnGoForward" 
                Click="btnGoForward_Click" />
        <Button Content="&lt;&lt;" Name="btnGoBack" Click="btnGoBack_Click" />


The code looks like this :

 1: public partial class MainPage : PhoneApplicationPage
 2: {
 3:     int nrOfPics;
 4:     int picNr = 0;
 5:     MediaLibrary ml;
 6:     BitmapImage img = new BitmapImage();
 8:     // Constructor
 9:     public MainPage()
 10:     {
 11:         InitializeComponent();
 12:     }
 14:     private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
 15:     {
 16:         ml = new MediaLibrary();
 17:         nrOfPics = ml.Pictures.Count;
 18:         MessageBox.Show(nrOfPics.ToString());
 20:         ShowImage();
 21:     }
 23:     private void ShowImage()
 24:     {
 25:         img.SetSource(ml.Pictures[picNr].GetImage());
 26:         image1.Source = img;
 27:     }
 29:     private void btnGoBack_Click(object sender, RoutedEventArgs e)
 30:     {
 31:         if (--picNr<0)
 32:         {
 33:             picNr = nrOfPics - 1;
 34:         }
 35:         ShowImage();
 36:     }
 38:     private void btnGoForward_Click(object sender, RoutedEventArgs e)
 39:     {
 40:         if (++picNr>=nrOfPics)
 41:         {
 42:             picNr = 0;
 43:         }
 44:         ShowImage();
 45:     }
 46: }



Let's now return to the application created during my previous blog post. In the "Save Img" code we opened another page that simply showed the image with copyright-message. Let's now change the loaded-event of the WrittenImage-page so we can save the image :

WriteableBitmap bmp = PhoneApplicationService.Current.State["bmp"] as WriteableBitmap;
writtenImage.Source = bmp;
MediaLibrary ml = new MediaLibrary();
Stream stream = new MemoryStream();
bmp.SaveJpeg(stream, bmp.PixelWidth, bmp.PixelHeight, 0, 100);
ml.SavePicture("u2uPic.jpg", stream);
MessageBox.Show("Picture Saved...");


The SaveJpeg-method from WritableBitmap gives me a Stream containing the image in jpg-format. SavePicture saves the image in the MediaLibrary. However: it doesn't work ! It took me some time to find out why: It seems that the position of the stream remains at the end-position. Insert this line of code just before the SavePicture-call to make it work:


It's working !! Cool.

Next step: let's deploy these two apps to my device and test. Not working ! How the hell is that possible ? Retesting in the emulator : works fine. Retesting on device: not working. Aaaaargh !! Disconnecting my device, going over to a colleague to ventilate my frustration and see that all of a sudden it is working !! Seems that for this thing to work, it needs to be disconnected from the PC.