Home > Metro, Windows 8 > Windows 8 Using WebCam

Windows 8 Using WebCam

The new Windows Runtime object model makes it very easy to access all kind of sensors and devices. In this example i’ll show, how to get images and videos from a connected / builtin webcam.

There are two ways how to get images or videos from the device:

  • CameraCaptureUI

The easiest way is using the builtin CameraCaptureUI object, which displays the system provided dialog always fullscreen and looks like this: image
The disadvantage of this approach is, that your app is not visible during capturing, because the CameraCaptureUI always takes up the whole screen and the user can only use the system provided settings dialogs. This dialog allows the user to crop the taken image or video immediately after recording and then returns the resulting image or video to your app.

  • MediaCapture

    Using the MediaCapture object model the system does not show any UI, but your app must display its own UI for preview and capturing the image or video.
    Although it takes a few more steps, it also allows much more finer control
    For more info on this way, scroll down to "How to use MediaCapture"

I’ll start from the minimalistic template app, which i’ve described in this post.

Sample on how to use the CameraCaptureUI:
Then we’ll add two button in the content area and label the first button "Get Image" and the second one "Get Video". Below we will place a Border control and above this a Image Control.

Should look like like this:

image   image

Fetching images using CameraCaptureUI

Interaction with the Webcam can only be done, if the user allows to do so.

Therefore the developer has to request access to the webcam. This can be done by opening the Package.appxmanifest and check the WebCam capability:

This will prompt the user on the first startup of the app with this question:

image 

image

Now we need a few lines of code to fetch the image from the webcam, save it to a temp folder and then read it into memory to display it in the image control.

The easiest way would be this:

private async void GetImageFromWebCamSimple()
{
    CameraCaptureUI camUI = new CameraCaptureUI();
    StorageFile storageFile = await camUI.CaptureFileAsync(CameraCaptureUIMode.Photo);
    if (storageFile != null)
    {
        IRandomAccessStream stream = await storageFile.OpenReadAsync();
        BitmapImage bitmapImage = new BitmapImage();
        bitmapImage.SetSource(stream);
        MyImageControl.Source = bitmapImage;
    }
}


Fetching the image from the webcam and storing it to disk is just the first 2 lines!!

A real world app would of course wrap the call to CaptureFileAsync() with a try block, because if the user denies the permission to use the webcam, then this would crash the app.

 

Fetching a video using CameraCaptureUI

Almost the same logic is needed to fetch a video, save it to a temporary file and then play it back on a MediaElement control:

private async void GetVideoFromWebCam()
{
    CameraCaptureUI camUI = new CameraCaptureUI();
    StorageFile storageFile = await camUI.CaptureFileAsync(CameraCaptureUIMode.Video);
    if (storageFile != null)
    {
        IRandomAccessStream stream = await storageFile.OpenReadAsync();
        MyMediaElement.SetSource(stream, "image/jpeg");
        MyMediaElement.Play();
    }
}

 

Sample on how to use MediaCapture

 

Also for this sample, i’ll start from the minimalistic template app, which i’ve described in

this post.

As UI elements we need a ImageControl for displaying the captured image and a MediaElement for replaying the captured video stream.

For recording the image or video, a CaptureElement must be added to the XAML code.

To use the webCam, the capabilities WebCam and Microphone must be checked in the Package.AppxManifest.

 

image

 

  1. The first step is to find all the Cameradevices using DeviceInformation.FindAllAsync()
  2. The next step is to create a Storagefile for the image or video
  3. Then a new MediaCapture object must be created
  4. A new MediaCaptureInitializationSettings object must be created and the member VideoDeviceId must be set to one of the Ids of the found cameras.
  5. After this, the InitializeAsync(settings) call on the MediaCapture object must be made and then either one of this functions can be called:
  • CapturePhotoToStorageFileAsync
  • StartRecordToStorageFileAsync

Both will save the image or video into the given StorageFile.

Optionally the StartPreviewAsync() function can be called to get a preview of the current image.

MediaCapture mc = null;
StorageFile videoStorageFile = null;

private void btnStartVideo_Click_1(object sender, RoutedEventArgs e)
{
    StartRecordVideoUsingMediaCapture();
}

private void btnStopVideo_Click_1(object sender, RoutedEventArgs e)
{
    StopRecordVideoUsingMediaCapture();
}

private async void GetImageUsingMediaCapture()
{
    DeviceInformationCollection myDevices = 
        await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);

    if (myDevices.Count < 1)
    {
        await new MessageDialog("No Camera found!").ShowAsync();
        return;
    }
    // Create the image file
    StorageFolder localFolder = ApplicationData.Current.LocalFolder;
    string filename = "Pic_" + DateTime.Now.ToString("yyyy_MM_dd-hh_mm_ss") + ".jpg";
    StorageFile photoStorageFile = 
        await localFolder.CreateFileAsync(filename, 
                        CreationCollisionOption.ReplaceExisting);

    bool camAvailable = true;
    try
    {
        // Initialize MediaCapture
        mc = new MediaCapture();
        MediaCaptureInitializationSettings settings =
                    new MediaCaptureInitializationSettings();

        settings.VideoDeviceId = myDevices.ElementAt(0).Id;
        await mc.InitializeAsync(settings); // Will check for Capabilities here

        //// Define Image quality
        ImageEncodingProperties imageProperties = new ImageEncodingProperties();
        imageProperties.Subtype = "JPEG";
        imageProperties.Width = 640;
        imageProperties.Height = 400;
        
        await mc.CapturePhotoToStorageFileAsync(imageProperties, photoStorageFile);

        DisplayImageFromFileInImageControl(photoStorageFile);
    }
    catch (Exception ex)
    {
        camAvailable = false;
    }

    if (camAvailable == false)
    {
        await new Windows.UI.Popups.MessageDialog("No Webcam allowed?").ShowAsync();
    }

    if (photoStorageFile != null)
    {
        DisplayImageFromFileInImageControl(photoStorageFile);
    }
}

private async void StartRecordVideoUsingMediaCapture()
{
    DeviceInformationCollection myDevices = 
        await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);

    if (myDevices.Count < 1)
    {
        await new MessageDialog("No Camera found!").ShowAsync();
        return;
    }
    // Create the video file
    StorageFolder localFolder = ApplicationData.Current.LocalFolder;
    string filename = "Video_" + DateTime.Now.ToString("yyyy_MM_dd-hh_mm_ss") + ".mp4";
    videoStorageFile = await localFolder.CreateFileAsync(filename, 
                                        CreationCollisionOption.ReplaceExisting);

    bool camAvailable = true;
    try
    {
        btnStartVideo.IsEnabled = false;
        btnStopVideo.IsEnabled = true;

        // Initialize MediaCapture
        mc = new MediaCapture();
        MediaCaptureInitializationSettings settings = 
            new MediaCaptureInitializationSettings();

        settings.VideoDeviceId = myDevices.ElementAt(0).Id; // Use 1. camera
        await mc.InitializeAsync(settings); // Will check for Capabilities here

        // Also do Preview
        previewElement.Source = mc;
        await mc.StartPreviewAsync();

        MediaEncodingProfile recordProfile = 
            Windows.Media.MediaProperties.MediaEncodingProfile.CreateMp4(
                                                        VideoEncodingQuality.Auto);
        await mc.StartRecordToStorageFileAsync(recordProfile, videoStorageFile);
        lblStatus.Text = "Recording...";
    }
    catch (Exception ex)
    {
        camAvailable = false;
    }

    if (camAvailable == false)
    {
        await new Windows.UI.Popups.MessageDialog("No Webcam allowed?").ShowAsync();
    }
}

private async void StopRecordVideoUsingMediaCapture()
{
    btnStartVideo.IsEnabled = true;
    btnStopVideo.IsEnabled = false;

    await mc.StopRecordAsync();

    if (videoStorageFile != null)
    {
        lblStatus.Text = "Replay video...";
        DisplayVideo(videoStorageFile);
    }
}

#endregion Using MediaCapture 

#region Image / Video Display helpers
private async void DisplayImageFromFileInImageControl(StorageFile storageFile)
{
    IRandomAccessStream stream = await storageFile.OpenReadAsync();
    BitmapImage bitmapImage = new BitmapImage();

    bitmapImage.SetSource(stream);
    MyImageControl.Source = bitmapImage;
}

private async void DisplayVideo(StorageFile storageFile)
{
    IRandomAccessStream stream = await storageFile.OpenReadAsync();
    MyMediaElement.SetSource(stream, "image/jpeg");
    MyMediaElement.Play();
}        
#endregion

 .

Categories: Metro, Windows 8
  1. Freddy Beaufait
    July 22, 2015 at 10:23 pm

    The requirements for this webcam shouldn’t be a problem for many computer systems and laptops made throughout the last three years.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: