Monday, December 3, 2012

Windows Phone 7 Photo Upload

Recently I have developed a native Windows Phone 7 program to upload images to remote server.

MainPage.xaml

<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

            <ListBox Height="517" Margin="0,6,0,0" Name="listimge" VerticalAlignment="Top" Width="450">

                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <CheckBox Name="chk" /><Image Source="{Binding ImageFile}" Width="100" Height="100"/>
                            
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
            <Button Content="Upload" Height="72" HorizontalAlignment="Left" Margin="150,529,0,0" Name="uploadButton" 
            VerticalAlignment="Top" Width="160" Click="UploadClick" />

</Grid>


MainPage.xaml.cs

The below method is used to load image files from the Picture Gallery to the ListBox.
private MediaLibrary MyMediaLibrary { get; set; }

private void LoadImageGallery()
{
            MyMediaLibrary = new MediaLibrary();
            PictureCollection pictures = MyMediaLibrary.Pictures;
            foreach (Picture picture in pictures)
            {
                var image = new BitmapImage();
                image.SetSource(picture.GetImage());
                var mediaImage = new MediaImage {ImageFile = image};
                listimge.Items.Add(mediaImage);
            }
}

This method is used to upload the selected images(iterating through the ListBox to find the selected index) to the remote server.
private void UploadClick(object sender, RoutedEventArgs e)
{
            for (int i = 0; i < listimge.Items.Count; i++)
            {
                if (listimge.ItemContainerGenerator != null)
                {
                    var item = listimge.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem;
                    var tagregCheckBox = FindCheckBox<CheckBox>(item);
                    if (tagregCheckBox.IsChecked == true)
                    {
                        UploadImage(i);
                        tagregCheckBox.IsChecked = false;
                    }
                }
            }
}

Helper function which is used to identify the checked Checkboxses in the ListBox.
private T FindCheckBox<T>(DependencyObject parentElement) where T : DependencyObject
{
            int count = VisualTreeHelper.GetChildrenCount(parentElement);
            if (count == 0)
                return null;

            for (int i = 0; i < count; i++)

            {
                DependencyObject child = VisualTreeHelper.GetChild(parentElement, i);

                if (child != null && child is T)

                {
                    return (T) child;
                }
                var result = FindCheckBox<T>(child);
                if (result != null)
                    return result;
            }
            return null;
}

This method is used to find the image from image gallery, get the stream of the identified image and send it to the remote server.
private void UploadImage(int selectedIndex)
{
            const int BLOCK_SIZE = 4096;

            var uri = new Uri("http://10.20.10.71/MVCFile/File", UriKind.Absolute);


            var webClient = new WebClient();

            webClient.AllowReadStreamBuffering = true;
            webClient.AllowWriteStreamBuffering = true;

            Stream selectedImageStream = MyMediaLibrary.Pictures[selectedIndex].GetImage();


            webClient.OpenWriteCompleted += (s, args) =>

                                                {
                                                    using (var binaryReader = new BinaryReader(selectedImageStream ))
                                                    {
                                                        using (var binaryWriter = new BinaryWriter(args.Result))
                                                        {
                                                            long count = 0;
                                                            long fileSize = selectedImageStream .Length;
                                                            var bytes = new byte[BLOCK_SIZE];
                                                            do
                                                            {
                                                                bytes = binaryReader.ReadBytes(BLOCK_SIZE);
                                                                count += bytes.Length;
                                                                binaryWriter.Write(bytes);
                                                            } while (count < fileSize);
                                                        }
                                                    }
                                                };

            webClient.WriteStreamClosed += (s, args) => { MessageBox.Show("Send Complete"); };


            webClient.OpenWriteAsync(uri, "POST");

}

Finally add the 'LoadImageGallery' method to the constructor of MainPage.
// Constructor
public MainPage()
{
            InitializeComponent();
            LoadImageGallery();
}


Server side File Uploading Controller
public class FileController : Controller
{
       public ActionResult Index()
      {
            string filename = Server.MapPath(String.Format("{0}.jpg", "YourFileName"));

            try

            {
                using (var fs = new FileStream(filename, FileMode.Create))
                {
                    using (var bw = new BinaryWriter(fs))
                    {
                        using (var br = new BinaryReader(Request.InputStream))
                        {
                            long bCount = 0;
                            long fileSize = br.BaseStream.Length;
                            const int BLOCK_SIZE = 4096;
                            byte[] bytes = new byte[BLOCK_SIZE];
                            do
                            {
                                bytes = br.ReadBytes(BLOCK_SIZE);
                                bCount += bytes.Length;
                                bw.Write(bytes);
                            } while (bCount < fileSize);
                        }
                    }
                }

                return Json(new { Result = "Upload Complete" }, JsonRequestBehavior.AllowGet);

            }
            catch (Exception ex)
            {
                return Json(new { Result = "Upload Error", Message = ex.Message }, JsonRequestBehavior.AllowGet);
            }
      }
}













No comments:

Post a Comment