Scope
In this article, we'll see how to develop a Windows Phone app capable of automatically taking photos using the device's camera and uploading them to a web server by which they can be seen from a browser. In other words, we'll develop a sort of network camera / webcam that could be run from a smartphone or tablet to monitor a certain place from elsewhere. We'll use Visual Basic .NET for the app part, whereas the server-side coding will be done in PHP, as we've done in a previous article about geolocalization (refer to Geolocalize a device and store coordinates on Webserver for further information).Prerequisites
To use the code presented in the article, you'll need:- Windows 8.1
- Visual Studio with Windows Phone 8.1 SDK
- A local or hosted web server, with Apache
with PHP support enabled. Alternatively, the web server part could be written in ASP/ASP.NET.
Introduction
In this article I'll present a simple method to implement a sort of smartphone/tablet based webcam, useful to set up scenarios that can be evolved into a surveillance application and the like. A growing attention to the Iot application field causes us to be increasingly concerned and aware of the possibilities of interconnectivity of our daily use devices and I think the present could be a nice (though really basic) exercise in that direction.What we will do here is to use a Windows device as an automatic camera, to take pictures as a data stream at every predetermined second, to send them remotely to a PHP script that will consolidate them as a file on the remote webserver, making it available to be seen when standing anywhere that allows internet connections.
Let's start from the server part, to do some initial assumptions that will make clearer the app development.
Server-side scripts
As we've previously stated, we'll use PHP (and an Apache webserver) to setup a simple script capable of receiving a file that will be sent using the POST method, to store it and thus make it subsequently accessible to further HTTP requests, such as a browser navigation. The script is the most simple possible. It consists of the reception of a POST content (namely, "file" parameter), proceding then in opening an arbitrary file (that I've named "test.jpg"), writing in it what was sent in binary mode. Let's see it:
- <?php
- $content = $_POST['file'];
- $sfile = fopen("test.jpg", 'wb'); // 'wb' parameter means "write binary"
- fwrite($sfile, $content);
- fclose($sfile);
- ?>
Pretty self-explanatory with a minimum of PHP knowledge. Next, we will prepare another page that I've named "index.html", a plain HTML file in which our "test.jpg" will be shown.
- <title>Network Camera</title>
- <!-- Omissis: styles will be present in the full code -->
- <h1>Network Camera</h1>
- <div id="imgwrapper">
- <img src="test.jpg">
- </div>
To sum up this part of our project, we are speaking here about having a web server equipped by two simple scripts. The first one will be exploited by our Windows Phone app and it will receive a file remotely the data stream sent by the app itself, when the second one is simply a viewer for those data, encapsulating the sent data (in other words, a photo) in an IMG tag, to allow users to see it. Now we can implement our app to complete the work.
namespace to access our device's camera capabilities.
First, open Visual Studio and select from the Visual Basic template menù the Store Apps / Blank App (Windows Phone) template. It will create for us a simple layout based on a single page, namely MainPage.xaml, on that we will apply the necessary controls and business logic.

Let's see what elements we will include in our XAML.

First we have a CaptureElement, in other words a control in which we will render the camera preview, to observe what will be acquired as the image. A TextBox named txtRemUP will contain the remote address of our upload.php (useful in case our app must communicate with various hosts, instead of hardcoding an URI). A ToggleButton will allow us to start and stop image acquisition and last we have a couple of TextBlock for log purposes (the date and time of the last shot and upload), and a Canvas that will show us the last picture taken.


Automatic camera app for Windows Phone
In this section, we will develop our Windows Phone app that will consist of the following:- Automatic camera shooting
- Automatic photo upload (in other words submitting the photo to our upload.php page)
namespace to access our device's camera capabilities.First, open Visual Studio and select from the Visual Basic template menù the Store Apps / Blank App (Windows Phone) template. It will create for us a simple layout based on a single page, namely MainPage.xaml, on that we will apply the necessary controls and business logic.

Let's see what elements we will include in our XAML.

First we have a CaptureElement, in other words a control in which we will render the camera preview, to observe what will be acquired as the image. A TextBox named txtRemUP will contain the remote address of our upload.php (useful in case our app must communicate with various hosts, instead of hardcoding an URI). A ToggleButton will allow us to start and stop image acquisition and last we have a couple of TextBlock for log purposes (the date and time of the last shot and upload), and a Canvas that will show us the last picture taken.
App prerequisites
Since our application must require the use of a hardware device and network communications, we must set the app's Capabilities and Requirements accordingly. Thus, we must double-click on the Package.appxmanifest file (that was created by Visual Studio), accessing both the Capabilities and Requirements tabs, setting the camera and network flag as follows:

Camera initialization
On the the Code-side, the first thing to do is to initialize our camera when the app starts, setting the CaptureElement Source property accordingly. Please note that nearly all the events that will be presented will be asynchronous. Let's start with the OnNavigatedTo event that defines the moment in which a certain Page will be shown.- Protected Overrides Async Sub OnNavigatedTo(e As Navigation.NavigationEventArgs)
- cam = New Windows.Media.Capture.MediaCapture
- Await cam.InitializeAsync()
- mCanvas.Source = cam
- Await cam.StartPreviewAsync()
- End Sub
I've declared a MediaCapture variable, cam, as visible to the entire scope. Here we'll use the method InitializeAsync on it, to initialize our camera, binding the MediaCapture variable as the source of our CaptureElement control. A further call to the StartPreviewAsync method will result in a graphical rendering of the camera acquisition on the control.
On the Toggled event of our ToggleButton, we will control a Timer launch or its disposition, depending on the ToggleButton status.
On the Toggled event of our ToggleButton, we will control a Timer launch or its disposition, depending on the ToggleButton status.
- If toggler.IsOn Then
- t = New System.Threading.Timer(AddressOf Shoot, Nothing, TimeSpan.Zero, New TimeSpan(0, 0, 10))
- t.Change(30000, Threading.Timeout.Infinite)
- Else
- If Not (t Is Nothing) Then t.Dispose()
- End If
Photo capturing
The Shoot subroutine is as follows:- Public Async Sub Shoot(sender As Object)
- Dim imgFormat As ImageEncodingProperties = ImageEncodingProperties.CreateJpeg()
- stream = New Streams.InMemoryRandomAccessStream
- Await cam.CapturePhotoToStreamAsync(imgFormat, stream)
- Await stream.FlushAsync
- stream.Seek(0)
- Await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, AddressOf SetCanvas)
- Await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, AddressOf MarshalToggler)
- End Sub
In it, we define a RandomAccessStream that will be initialized by calling the method CapturePhotoToStreamAsync (from the MediaCapture variable). Simply as that, the calling to that method will access the camera to take a shot, proceeding to copy the image to a stream. At the end of our routine, you can see two Dispatchers towards two subroutines, the latter being simply a check on the ToggleButton status. The first one, though, calls upon the SetCanvas routine that will be used to save the image to our Canvas, but more importantly, to upload it on our webserver, using a POST towards our upload.php URI.
- Private Async Sub SetCanvas()
- tmpLab.Text = DateTime.Now.ToString
- Dim b As New BitmapImage()
- Await b.SetSourceAsync(stream)
- pCanvas.Source = b
- Dim io As Stream = stream.AsStreamForRead
- Dim buf(io.Length) As Byte
- io.Position = 0
- Await io.ReadAsync(buf, 0, io.Length)
- Dim httpClient As New HttpClient
- Dim form = New MultipartFormDataContent
- form.Add(New ByteArrayContent(buf, 0, buf.Length), "file")
- Dim response = Await httpClient.PostAsync(txtRemUP.Text, form)
- response.EnsureSuccessStatusCode()
- httpClient.Dispose()
- Dim sd As String = response.Content.ReadAsStringAsync().Result
- lastSent.Text = Date.Now.ToString
- End Sub
- Creation of a BitmapImage object, using the method SetSourceAsync, a new Bitmap is made from our RandomAccessStream, using it as the Source of our Canvas, in order to show the last picture taken.
- Creation of a simple Stream to access a Byte array from our original RandomAccessStream (our image). That will be needed to upload our data correctly
- Creation of a MultipartFormDataContent (in other words a "simulated" HTTP form, with the web awaited variable that we've named "file" when we've created our upload.php page)
- Physical upload of our image
- Imports System.Net.Http
- Imports Windows.Storage
- Imports Windows.Media.MediaProperties
- Public NotInheritable Class MainPage
- Inherits Page
- Dim t As System.Threading.Timer
- Dim cam As Windows.Media.Capture.MediaCapture
- Dim stream As Streams.InMemoryRandomAccessStream
- Protected Overrides Async Sub OnNavigatedTo(e As Navigation.NavigationEventArgs)
- cam = New Windows.Media.Capture.MediaCapture
- Await cam.InitializeAsync()
- mCanvas.Source = cam
- Await cam.StartPreviewAsync()
- End Sub
- Private Async Sub SetCanvas()
- tmpLab.Text = DateTime.Now.ToString
- Dim b As New BitmapImage()
- Await b.SetSourceAsync(stream)
- pCanvas.Source = b
- Dim io As Stream = stream.AsStreamForRead
- Dim buf(io.Length) As Byte
- io.Position = 0
- Await io.ReadAsync(buf, 0, io.Length)
- Dim httpClient As New HttpClient
- Dim form = New MultipartFormDataContent
- form.Add(New ByteArrayContent(buf, 0, buf.Length), "file")
- Dim response = Await httpClient.PostAsync(txtRemUP.Text, form)
- response.EnsureSuccessStatusCode()
- httpClient.Dispose()
- Dim sd As String = response.Content.ReadAsStringAsync().Result
- lastSent.Text = Date.Now.ToString
- End Sub
- Private Sub MarshalToggler()
- If toggler.IsOn Then
- t = New System.Threading.Timer(AddressOf Shoot, Nothing, TimeSpan.Zero, New TimeSpan(0, 0, 10))
- t.Change(30000, Threading.Timeout.Infinite)
- Else
- If Not (t Is Nothing) Then t.Dispose()
- End If
- End Sub
- Public Async Sub Shoot(sender As Object)
- Dim imgFormat As ImageEncodingProperties = ImageEncodingProperties.CreateJpeg()
- stream = New Streams.InMemoryRandomAccessStream
- Await cam.CapturePhotoToStreamAsync(imgFormat, stream)
- Await stream.FlushAsync
- stream.Seek(0)
- Await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, AddressOf SetCanvas)
- Await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, AddressOf MarshalToggler)
- End Sub
- Private Sub toggler_Toggled(sender As Object, e As RoutedEventArgs)
- MarshalToggler()
- End Sub
- End Class
Let's see an example of the execution of the project.
An overall test
A simple test will consist of setting up the webserver and the device, launch the Windows Phone app awaiting it to take and upload photos, checking for them later using a browser, visiting the HTML page we've created before:


Source Code
The complete source code used in the present article can be downloaded at: https://code.msdn.microsoft.com/Get-Automatic-Pictures-3b3875dd
Bibliography
- HttpClient
class
- InMemoryRandomAccessStream
class
- MultipartFormDataContent
class
- Windows.Media.Capture
namespace

Santhakumar MunuswamyPosted Aug 16, 2015, 2:20 AM
Good Article. Thanks for sharing
Sibeesh VenuPosted Aug 15, 2015, 4:38 AM
Nice Share :)
Sam HobbsPosted Aug 14, 2015, 10:16 PM
I wonder if this is the type of application hat many hackers are happy to find. If a hacker can hack your application then they can spy on you, correct?
Carmelo La MonicaPosted Aug 14, 2015, 2:12 PM
Good Article :)
Rajeesh MenothPosted Aug 14, 2015, 1:38 PM
Good One
Emiliano MussoPosted Aug 14, 2015, 1:13 PM
Thank you for your appreciation
Pankaj Kumar ChoudharyPosted Aug 14, 2015, 12:49 PM
Nice article sir.......
Mahesh ChandPosted Aug 14, 2015, 11:49 AM
Nice!