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);
}));
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);
}
}