.net, Computer Vision, UWP, Visual Studio, Windows Store Apps

How to use the camera on your device with C# in a UWP application: Part #2, how to focus the preview

In the previous part of the series, we looked at how to preview your device’s camera output.

This part is about how to focus the device using C#. Not all devices will be capable of focussing – for example, a normal laptop webcam won’t be able to focus, but a Nokia 1520 can focus. Fortunately, we don’t need to guess – testing support for focussing is part of the API provided for Windows UWP apps. We can test this by using the “_mediaCapture” object, which we created in the code shown in Part #1.

if (_mediaCapture.VideoDeviceController.FocusControl.Supported)
{
    // Code here is executed if focus is supported by the device.
}

On my phone,  I’d like to use the camera button when it’s half-pressed to focus the image. I’m able to do this in a UWP app, but I need to add a reference to a UWP library first first.

Setting up mobile extension references

In the solution view in VS2015, right click on the “References” node, and select “Add Reference…”.

screenshot.1461183352

The window that appears is called the “Reference Manager”. On the left hand menu, expand the “Universal Windows” node, and select “Extensions”. In the list of extensions, tick the box for “Windows Mobile Extensions for the UWP”. Now click OK.

screenshot.1461183496

Testing for hardware buttons on the device, and handling events

Obviously enough, we’ve now added a reference to a library which allows you to test for the availability of certain sensors which are specific to a mobile device, such as the hardware button used to take a picture.

if (ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"))
{
    // This code will only run if the HardwareButtons type is present.
}

The Camera button has three events – CameraPressed, CameraHalfPressed, and CameraReleased. I’m interested in intercepting the CameraHalfPressed event for focussing, so I’ve assigned the event handler in the code below, and put this in the constructor for the MainPage class.

if (ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"))
{
    HardwareButtons.CameraHalfPressed += HardwareButtons_CameraHalfPressed;
}

The event handler is shown below, including the snippet of code to test if focussing is supported.

private void HardwareButtons_CameraHalfPressed(object sender, CameraEventArgs e)
{
    if (_mediaCapture.VideoDeviceController.FocusControl.Supported)
    {
        // Focussing code is here.
    }
}

Focus range and focus mode

To focus the camera device, I need to configure the focus control of the _mediaCapture object – this means getting the focus mode and focus range. We can get the supported ranges and modes from the focus control object, and then assign these as settings. Finally, we need to call the asynchronous focus method. The code below shows how this works.

private async void HardwareButtons_CameraHalfPressed(object sender, CameraEventArgs e)
{
    // test if focus is supported
    if (_mediaCapture.VideoDeviceController.FocusControl.Supported)
    {
        // Get the focus control from the _mediaCapture object.
        var focusControl = _mediaCapture.VideoDeviceController.FocusControl;
 
        // Try to get full range autofocus, but settle for the first supported range.
        var focusRange = focusControl.SupportedFocusRanges.Contains(AutoFocusRange.FullRange) ? AutoFocusRange.FullRange : focusControl.SupportedFocusRanges.FirstOrDefault();
 
        // Try to get the focus mode for focussing just once, but settle for the first supported one.
        var focusMode = focusControl.SupportedFocusModes.Contains(FocusMode.Single) ? FocusMode.Single : focusControl.SupportedFocusModes.FirstOrDefault();
 
        // Now configure the focus control with the range and mode as settings.
        focusControl.Configure(
            new FocusSettings
            {
                Mode = focusMode,
                AutoFocusRange = focusRange
            });
 
        // Finally wait for the camera to focus.
        await focusControl.FocusAsync();
    }
}

So again, only a few lines of code are needed to register a button press event, and then configure the focus control. Hopefully this helps someone trying to set up focussing.

In the next part, I’ll look at how to change our code to actually capture an image when we fully press the camera button.