This article is Day #21 in a series called 31 Days of Windows 8. Each of the articles in this series will be published for both HTML5/JS and XAML/C#. You can find additional resources, downloads, and source code on our website.
Today, we’re going to kick off a long line of article on the sensors that Windows 8 has access to. We are starting with capturing data from the camera. This can be both photos and video, and we’ll take a look at both in this article.
Updating our Manifest
As we have had to do for many of our topics in this series, we need to start by updating our package.appxmanifest file to enable the use of the user’s webcam and microphone. You do that by checking two boxes in the Capabilities section, like this:
Without these, you won’t be able to use these technologies, so make sure you’ve handled this first.
Capturing a Still Image
One of the great things about capturing media in Windows 8 is that practically all of the work is done for you. That being said, there are some things to consider. First, your app will prompt the user for permission to use your camera and microphone when you try to access that hardware.
Much like Lock Screen access, you only get one shot at this. Thankfully, if the user clicks “Block” for whatever reason (maybe because it’s the highlighted option?), the camera “display” dialog will prompt the user to change their settings, like this:
And if the user opens their Settings charm, they’ll find a “Permissions” option, like this:
Clicking the “Permissions” link will bring up this menu, which is generated based on the choices we made in our appxmanifest file.
The user will always have the ability to turn this on and off, but since the Camera Dialog handles this case for us, we only need to make sure we actually had an image object returned to us. Here’s the three lines of code that are required to capture an image from the camera, and return it as a StorageFile object:
CameraCaptureUI camera = new CameraCaptureUI();
camera.PhotoSettings.CroppedAspectRatio = new Size(16, 9);
StorageFile photo = await camera.CaptureFileAsync(CameraCaptureUIMode.Photo);
Technically, only two of those lines are required. The 2nd line, which sets the CroppedAspectRatio is not required, but highly recommended. When the Camera Dialog opens, the user is presented with a full-screen view of their webcam.
They have a couple of options (like resolution and using a timer), and they can tap on the screen (or click) to initiate the camera capture. If we specify a CroppedAspectRatio, this is what the user will see (feel free to comment on the beard, the EMPTY Red Bull fridge, or the overall messiness of my home office):
You can see that there are 4 white circles on the screen which indicate the cropping region. The user has the ability to change the size and position of this box, but by specifying a CroppedAspectRatio, we can force them to choose an image that is the shape we’re expecting. I used 16:9 in my example, but you could also do 1:1 to require a square image. Without this option, the user is not forced to crop, but has the option to crop it any size, from the bottom menu options:
Which, if they choose Crop, will allow them to select any portion of the captured image:
Ultimately, we’re waiting for the user to click the OK button, which will return the image data to our application, letting us then use this image however we’d like. Here’s a quick video of that entire process:
And here’s the code I’m using to make all of this happen:
CameraCaptureUI camera = new CameraCaptureUI();
camera.PhotoSettings.CroppedAspectRatio = new Size(16, 9);
StorageFile photo = await camera.CaptureFileAsync(CameraCaptureUIMode.Photo);
if (photo != null)
{
BitmapImage bmp = new BitmapImage();
IRandomAccessStream stream = await photo.OpenAsync(FileAccessMode.Read);
bmp.SetSource(stream);
ImageSource.Source = bmp;
ImageSource.Visibility = Visibility.Visible;
}
As you can see, our first three lines are there, and then I check to see if we had actual data returned to us. If we do, we read the data into a BitmapImage object, and set that as the source of an Image control I have on my page named ImageSource. Finally, I turn the visibility of that Image control on, so that the user can see the image. That’s pretty much all you need to do to capture an image in Windows 8 using C# and XAML. Next, we’ll go though the same process for video.
Capturing a Video
Thankfully, video is practically identical to video. There are a few differences related to how we interact with the data once it’s been returned, but in general, the process is very similar.
When we were talking about capturing photos, I didn’t dive too deep into the additional options that were available because they were limited (you can decide between JPG or PNG files, for example). With video, however, I thought I’d mention a few of them. So, here’s my code for capturing video, with a few additional options sprinked in:
CameraCaptureUI videocamera = new CameraCaptureUI();
videocamera.VideoSettings.Format = CameraCaptureUIVideoFormat.Mp4;
videocamera.VideoSettings.AllowTrimming = true;
videocamera.VideoSettings.MaxDurationInSeconds = 30;
videocamera.VideoSettings.MaxResolution = CameraCaptureUIMaxVideoResolution.HighestAvailable;
StorageFile video = await videocamera.CaptureFileAsync(CameraCaptureUIMode.Video);
if (video != null)
{
IRandomAccessStream stream = await video.OpenAsync(FileAccessMode.Read);
VideoSource.SetSource(stream, "video/mp4");
VideoSource.Visibility = Visibility.Visible;
}
Let’s talk about a few of these things. First, we can specify between MP4 video or WMV. You won’t see a difference between the two formats until you try to share that video with other systems and platforms. MP4 is far more widely used than WMV, but it’s also a larger format, so that’s worth considering.
Second, I’ve turned on “AllowTrimming” which allows the user to select the segment of their recorded video that they would like to use. They’ll get a user interface similar to this, where they can drag either end of the video using the white crop circles:
Third, I’ve specified a MaxDurationInSeconds, which limits the maximum length of video a user can provide. If they record more than that duration, they’ll be able to select which 30 seconds (or the duration you specify) that they’d like to use. I can see this being useful for businesses like Match.com where people make profile videos, but they don’t want them to run on forever.
Finally, I’ve also specified a MaxResolution. This allows us to manage the resolution that the user can record with, which can also help with the final file size we end up with. You have four choices:
Otherwise, we end up with a very similar result to our camera efforts. I set the source of my MediaElement, VideoSource to our new data stream, and turn the visibility of that MediaElement to Visible.
Summary
In short, capturing photos and videos from your user’s camera is very easy, as well as customizable. Most of the complicated UI is handled directly by Windows 8, so we don’t have to worry about most of the interaction with the user. I’ve provided screenshots and a video in this article, but the best way to get a feel for this process is to work with a real application.
To download a working solution that uses all of the code from this article, click the icon below:
Tomorrow, we’re going to play with a very cool technology called Play To. It allows us to stream media from a device to televisions, Xbox 360 devices, and more. See you then!
Leave a Reply