Documentation

Hardware Control

Camera Settings

The first part of the series will present a general overview of what is possible with the Wikitude SDK.

Camera Position

The camera position defines the location of the camera, it can be retrieved by calling getPosition of a Camera object. Positions can be :

  • Unspecified : used for external webcams.
  • Back : camera located in the back panel of the device.
  • Front : camera located in the front panel of the device.

Camera Focus Mode

The camera focus mode defines which focus mode is used internally by the camera. It can be set by using CameraManager::setFocusMode.

The camera focus mode can be one of the following modes:

  • Continuous: Is the default if the device supports it, in this mode the camera will try to refocus automatically when necessary.
  • Single: Can force the camera to refocus once on the current view. If you need to change focus you can set this value again.
  • Manual: Is disabling auto focus and will set the focus to the specified manual focus distance.

Manual Camera Focus

The focus distance ranges from the minimum to the maximum distance. These values can be retrieved calling CameraManager::getMinimumFocusDistance and CameraManager::getMaximumFocusDistance. It can be set by using CameraManager::setManualFocusDistance

Manual Camera Exposure

The exposure time ranges between minimum and maximum exposure times that can be retrieved by calling CameraManager::getMinimumExposureTime() and CameraManager::getMaximumExposureTime(). Manual Exposure time can be set by calling CameraManager::setExposureTime().

Camera Zoom

Digital zoom can be controlled by using CameraManager::setZoomFactor.

To get the minimum and maximum zoom level use CameraManager::getMinimumZoomFactor and CameraManager::getMaximumZoomFactor.

Flashlight

The flashlight can be turned on and off by using CameraManager::enableTorch and CameraManager::disableTorch.

Focus / Exposure at point of interest

Wikitude Native SDK for UWP supports focusing / exposing at a point of interest. Support for these features can be checked calling respectively isExposurePointOfInterestSupported() and isFocusPointOfInterestSupported(). To set the point of interest, call setPointOfInterest, with the corrdinate of point to focuse/expose at, and enable focus and/or exposure .

Camera Controls

The CameraManager allows you to change capture device specific settings during an active capture session. It lets you change e.g.

  • the capture device position
  • the capture device focus mode
  • the capture device focus distance
  • the capture device zoom level

A valid reference to a CameraManager object can be retrieved from the WikitudeNativeSDK method getCameraManager.

The CameraManager object allows control over the current camera, but also allow us to list available cameras, change the active camera or image format, as well as being notified when the camera become active or inactive.

To get a list of available cameras, getAvailableCameras and findCameraMatchingCharacteristics methods are used. The former lists all available cameras while the later allow filtering on CameraPosition and CameraResolution.

In our sample, we use getAvailableCameras to fill a combo box with the list of cameras of the system :

cameraManager->getAvailableCameras(ref new CameraDiscoveryHandler([wr, cameraManager](IVector<Camera ^> ^ cameras_) {
   CameraSettingsPage ^ page = wr.Resolve<CameraSettingsPage>();
   page->_cameraList = ref new Platform::Collections::Vector<wikitude::sdk::uwp::Camera^>(begin(cameras_), end(cameras_));
   page->CameraComboBox->ItemsSource = page->_cameraList;
   for (auto camera : page->_cameraList) {
      if (camera->getPosition() == CameraPosition::Back) {
         page->CameraComboBox->SelectedItem = camera;
      }
   }
   page->CameraComboBox->IsEnabled = true;
   page->_cameraSelectionToken = page->CameraComboBox->SelectionChanged += ref new Controls::SelectionChangedEventHandler(page, &CameraSettingsPage::cameraComboBox_SelectionChanged);
}));
Important: Use the cameraManager->getAvailableCameras method to list attached devices and use the Wikitude SDK with external webcams.

To set the active camera, we call setActiveCamera with a Camera reference obtained with getAvailableCameras. In our example, we call this method in the SelectionChanged event handler from the camera list combo box :

void CameraSettingsPage::cameraComboBox_SelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e)
{
   auto cameraManager = _sdk->getCameraManager();
   cameraManager->setActiveCamera(_cameraList->GetAt(CameraComboBox->SelectedIndex));
}

We can register to CameraManager's event CameraOpenedEventHandler and CameraClosedEventHandler to be notified when the camera is available to control. In our example, we use these event to enable/disable camera control UI, and to query the CameraManager object about available controls.

cameraManager->CameraOpenedEventHandler += ref new CameraOpenedHandler([wr](CameraManager^ sender_) {
   CameraSettingsPage ^ page = wr.Resolve<CameraSettingsPage>();
   if (page) {
         page->InitCameraControls();
   }            
});
cameraManager->CameraClosedEventHandler += ref new CameraClosedHandler([wr](CameraManager^ sender_) {
   CameraSettingsPage ^ page = wr.Resolve<CameraSettingsPage>();
   if (page) {
         page->DisableCameraControls();
   }
});

CameraManager implements CameraControls interface to allow us to to control the current active camera.

First, we check if the active camera supports zoom control. If so, we retrieve current settings to populate the UI and enable the zoom slider.

if (cameraControls->isZoomControlSupported()) {
      zoomSlider->Minimum = cameraControls->getMinimumZoomFactor();
      zoomSlider->Maximum = cameraControls->getMaximumZoomFactor();
      zoomSlider->StepFrequency = cameraControls->getZoomFactorStep();
      zoomSlider->Value = cameraControls->getZoomFactor();
      zoomSlider->IsEnabled = true;
      _zoomSliderToken = zoomSlider->ValueChanged += ref new RangeBaseValueChangedEventHandler(this, &CameraSettingsPage::zoomSlider_ValueChanged);
}
else {
      zoomSlider->IsEnabled = false;
}

To control the zoom level, we attach an event handler to the ValueChanged event from the zoom slider:

void CameraSettingsPage::zoomSlider_ValueChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs^ e)
{
   wikitude::sdk::uwp::CameraControls^ cameraControls = _sdk->getCameraManager();
   auto zoomFactor = zoomSlider->Value;
   cameraControls->setZoomFactor(zoomFactor);
}

Next we check support for manual focus control, and then enable and populate the UI as we did for zoom control :

if (cameraControls->isManualFocusSupported()) {
      FocusComboBox->IsEnabled = true;
      focusSlider->Minimum = cameraControls->getMinimumFocusDistance();
      focusSlider->Maximum = cameraControls->getMaximumFocusDistance();
      focusSlider->StepFrequency = 1;
      focusSlider->Value = cameraControls->getManualFocusDistance();
}
else {
      FocusComboBox->IsEnabled = false;
}

We attach a handler to the ValueChanged event of the focus slider :

void CameraSettingsPage::focusSlider_ValueChanged(Platform::Object ^sender, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs ^e)
{
   wikitude::sdk::uwp::CameraControls^ cameraControls = _sdk->getCameraManager();
   auto focusDistance = focusSlider->Value;
   cameraControls->setManualFocusDistance(focusDistance);
}

Focus and exposure point of interest are not controlled through UI elements but user input. The example class implements a tap to surface handler, where the coordinates of the tap are calculated, and then passed to the setPointOfInterest method:

void CameraSettingsPage::swapChainPanel_Tapped(Platform::Object^ sender, Windows::UI::Xaml::Input::TappedRoutedEventArgs^ e)
{
    if (e->OriginalSource->Equals(sender) && (_tapToExposureEnabled || _tapToFocusEnabled)) {
        auto pos = e->GetPosition(dynamic_cast<Windows::UI::Xaml::UIElement^>(sender));
        wikitude::sdk::uwp::Point2i point;
        point.x = pos.X * swapChainPanel->CompositionScaleX;
        point.y = pos.Y * swapChainPanel->CompositionScaleY;
        canvas->SetLeft(focusMarker, pos.X - focusMarker->ActualWidth / 2.);
        canvas->SetTop(focusMarker, pos.Y - focusMarker->ActualHeight / 2.);
        focusMarker->Visibility = Windows::UI::Xaml::Visibility::Visible;
        auto cameraControls = _sdk->getCameraManager();
        cameraControls->setPointOfInterest(point, _tapToFocusEnabled, _tapToExposureEnabled);
    }
}