February 8, 2012

Downloading images and storing in PictureLibrary

Recently, one of my friend Kunal and I were discussing about storing images in Picture Library on Windows Phone. At first, it looks pretty simple task as there are launcher/choosers concepts to handle this kind of situation. People can use PictureChooseTask to select a particular picture from Picture Library, however saving picture to the same is bit tricky. So, here is the solution.

Saving image files (from your application or downloaded from web site) to Picture Library is multistep procedure like:

  • Downloading image from Web or capturing image within your application.
  • Create StreamResourceInfo and StreamReader for returned image stream.
  • Temporarily storing image in application’s IsolatedStorage
  • Creating bitmap image from the temporary image and storing it in Picture Library.

If you’ve your image in your application (may be content or resource), you can follow MSDN Code Sample for storing that image into Picture Library. However, if you’re downloading the image from web, following code will help you.

  • Add reference to following required assemblies or include them into your project:
 using Microsoft.Xna.Framework.Media;  
using System.Windows.Resources;
using System.Windows.Media.Imaging;
using System.IO.IsolatedStorage;
using System.IO;


  • On click of a button, download image from web using WebClient. Along with it add an event handler (for callback) as this method is going to run asynchronously.
 private void button1_Click(object sender, RoutedEventArgs e)  
{
WebClient web = new WebClient();
web.OpenReadCompleted += web_OpenReadCompleted;
web.OpenReadAsync(
new Uri("http://iunlockjoy.cloudapp.net/Content/images/phone2.jpg",
UriKind.Absolute));
}


  • On callback read the image and store it in IsolatedStorage, read it and store in Picture Library.  
 void web_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)  
{
//Get the image stream and read it
var imageStream = new StreamResourceInfo(e.Result, null);
var streamReader = new StreamReader(imageStream.Stream);
//Create temp holder for image
String tempJPEG = "TempJPEG";
//Get application's ISOStore & check for prior files with same name.
var myStore = IsolatedStorageFile.GetUserStoreForApplication();
if (myStore.FileExists(tempJPEG))
{
myStore.DeleteFile(tempJPEG);
}
//Create a stream to save the temp file
IsolatedStorageFileStream myFileStream = myStore.CreateFile(tempJPEG);
byte[] contents;
//Binary read to read the image stream
BinaryReader bReader = new BinaryReader(streamReader.BaseStream);
contents = bReader.ReadBytes((int)streamReader.BaseStream.Length);
//Actually creating bitmap here
BitmapImage bitmap = new BitmapImage();
bitmap.CreateOptions = BitmapCreateOptions.None;
bitmap.SetSource(imageStream.Stream);
WriteableBitmap wb = new WriteableBitmap(bitmap);
//Saving this bitmap into ISOStore
wb.SaveJpeg(myFileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);
//Don't forget to close the stream
myFileStream.Close();
//Open stream to read the file
myFileStream = myStore.OpenFile(tempJPEG, FileMode.Open, FileAccess.Read);
//Get access to user's media library for pictures, videos, music files
MediaLibrary library = new MediaLibrary();
// Save the image to the saved pictures album.
Picture pic = library.SavePicture("SavedPicture.jpg", myFileStream);
MessageBox.Show("Image saved to saved pictures album");
//Again, don't FORGET to close the stream
myFileStream.Close();
}


  • Now, navigate to Picture Library > Saved Pictures and you should have the image stored over there.

I’ll really appreciate if Microsoft, will come up with PictureSaveTask (launcher) to save the picture in Picture Library to make the consistent programing methodology.


You can download the entire source code from my SkyDrive. I hope, it will help you to build some great apps. Happy Coding.


Namaste


Mayur Tendulkar | www.mayurtendulkar.com