Manuelle Kamerasteuerelemente für Foto- und Videoaufnahmen
In diesem Artikel erfahren Sie, wie Sie mit den manuellen Bedienelementen des Geräts verbesserte Foto- und Videoaufnahmeszenarien einschließlich optischer Bildstabilisierung und sanftem Zoom ermöglichen.
Die in diesem Artikel besprochenen Steuerelemente werden alle nach demselben Muster zu Ihrer Anwendung hinzugefügt. Prüfen Sie zunächst, ob das Steuerelement auf dem aktuellen Gerät, auf dem Ihre Anwendung ausgeführt wird, unterstützt wird. Wenn die Steuerung unterstützt wird, stellen Sie den gewünschten Modus für die Steuerung ein. Wenn ein bestimmtes Steuerelement auf dem aktuellen Gerät nicht unterstützt wird, sollten Sie das Oberflächenelement, mit dem der Benutzer die Funktion aktivieren kann, in der Regel deaktivieren oder ausblenden.
Der Code in diesem Artikel wurde aus dem Camera Manual Controls SDK Beispiel übernommen. Sie können das Beispiel herunterladen, um den verwendeten Code im Kontext zu sehen oder um das Beispiel als Ausgangspunkt für Ihre eigene Anwendung zu verwenden.
Hinweis
Dieser Artikel baut auf Konzepten und Code auf, die unter Allgemeine Foto-, Video- und Audioaufnahme mit „MediaCapture“ erläutert werden. Dort werden die Schritte für die Implementierung einer grundlegenden Foto- und Videoaufnahme beschrieben. Wir empfehlen Ihnen, sich mit dem grundlegenden Medienaufnahmemuster in diesem Artikel vertraut zu machen, bevor Sie sich komplexeren Aufnahmeszenarien zuwenden. Der Code in diesem Artikel setzt voraus, dass Ihre App bereits über eine korrekt initialisierte MediaCapture-Instanz verfügt.
Alle in diesem Artikel besprochenen Gerätesteuerungs-APIs sind Mitglieder des Namespace Windows.Media.Devices.
using Windows.Media.Devices;
Exposure (Belichtung)
Mit ExposureControl können Sie die Verschlusszeit für die Foto- oder Videoaufnahme einstellen.
In diesem Beispiel wird ein Schieberegler verwendet, um den aktuellen Belichtungswert einzustellen, und ein Kontrollkästchen, um die automatische Belichtungsanpassung zu aktivieren.
<Slider Name="ExposureSlider" ValueChanged="ExposureSlider_ValueChanged"/>
<TextBlock Name="ExposureTextBlock" Text="{Binding ElementName=ExposureSlider,Path=Value}"/>
<CheckBox Name="ExposureAutoCheckBox" Content="Auto" Checked="ExposureCheckBox_CheckedChanged" Unchecked="ExposureCheckBox_CheckedChanged"/>
Überprüfen Sie, ob das aktuelle Aufnahmegerät die ExposureControl unterstützt, indem Sie die Eigenschaft Unterstützt überprüfen. Wenn das Steuerelement unterstützt wird, können Sie die Benutzeroberfläche für diese Funktion anzeigen und aktivieren. Setzen Sie den Status des Kontrollkästchens, das anzeigt, ob die automatische Belichtungsanpassung derzeit aktiv ist, auf den Wert der Eigenschaft Auto.
Der Belichtungswert muss innerhalb des vom Gerät unterstützten Bereichs liegen und ein Inkrement der unterstützten Schrittweite sein. Rufen Sie die unterstützten Werte für das aktuelle Gerät ab, indem Sie die Eigenschaften Min, Max und Step überprüfen, die zum Festlegen der entsprechenden Eigenschaften des Schieberegler-Steuerelements verwendet werden.
Setzen Sie den Wert des Schieberegler-Steuerelements auf den aktuellen Wert des ExposureControl , nachdem Sie die Registrierung des ValueChanged-Ereignishandlers aufgehoben haben, damit das Ereignis nicht ausgelöst wird, wenn der Wert gesetzt wird.
var exposureControl = _mediaCapture.VideoDeviceController.ExposureControl;
if (exposureControl.Supported)
{
ExposureAutoCheckBox.Visibility = Visibility.Visible;
ExposureSlider.Visibility = Visibility.Visible;
ExposureAutoCheckBox.IsChecked = exposureControl.Auto;
ExposureSlider.Minimum = exposureControl.Min.Ticks;
ExposureSlider.Maximum = exposureControl.Max.Ticks;
ExposureSlider.StepFrequency = exposureControl.Step.Ticks;
ExposureSlider.ValueChanged -= ExposureSlider_ValueChanged;
var value = exposureControl.Value;
ExposureSlider.Value = value.Ticks;
ExposureSlider.ValueChanged += ExposureSlider_ValueChanged;
}
else
{
ExposureAutoCheckBox.Visibility = Visibility.Collapsed;
ExposureSlider.Visibility = Visibility.Collapsed;
}
Holen Sie sich im ValueChanged-Ereignishandler den aktuellen Wert des Steuerelements und setzen Sie den Belichtungswert durch den Aufruf SetValueAsync.
private async void ExposureSlider_ValueChanged(object sender, Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
{
var value = TimeSpan.FromTicks((long)(sender as Slider).Value);
await _mediaCapture.VideoDeviceController.ExposureControl.SetValueAsync(value);
}
Schalten Sie im Ereignishandler CheckedChanged des Kontrollkästchens für die automatische Belichtung die automatische Belichtungseinstellung ein oder aus, indem Sie SetAutoAsync aufrufen und einen booleschen Wert übergeben.
private async void ExposureCheckBox_CheckedChanged(object sender, RoutedEventArgs e)
{
if(! _isPreviewing)
{
// Auto exposure only supported while preview stream is running.
return;
}
var autoExposure = ((sender as CheckBox).IsChecked == true);
await _mediaCapture.VideoDeviceController.ExposureControl.SetAutoAsync(autoExposure);
}
Wichtig
Der automatische Belichtungsmodus wird nur unterstützt, während der Vorschaustream läuft. Vergewissern Sie sich, dass der Vorschaustream läuft, bevor Sie die automatische Belichtung einschalten.
Belichtungskorrektur
Unter Belichtungskorrektur können Sie die Belichtungskorrektur einstellen, die bei Foto- oder Videoaufnahmen verwendet wird.
In diesem Beispiel wird ein Schieberegler verwendet, um den aktuellen Wert der Belichtungskorrektur einzustellen.
<Slider Name="EvSlider" ValueChanged="EvSlider_ValueChanged"/>
<TextBlock Text="{Binding ElementName=EvSlider,Path=Value}" Name="EvTextBlock"/>
Überprüfen Sie, ob das aktuelle Aufnahmegerät die ExposureCompensationControl unterstützt, indem Sie die Eigenschaft Unterstützt überprüfen. Wenn das Steuerelement unterstützt wird, können Sie die Benutzeroberfläche für diese Funktion anzeigen und aktivieren.
Der Wert für die Belichtungskorrektur muss innerhalb des vom Gerät unterstützten Bereichs liegen und ein Inkrement der unterstützten Schrittweite sein. Rufen Sie die unterstützten Werte für das aktuelle Gerät ab, indem Sie die Eigenschaften Min, Max und Step überprüfen, die zum Festlegen der entsprechenden Eigenschaften des Schieberegler-Steuerelements verwendet werden.
Setzen Sie den Wert des Schieberegler-Steuerelements auf den aktuellen Wert des ExposureCompensationControl, nachdem Sie die Registrierung des ValueChanged Ereignishandlers aufgehoben haben, so dass das Ereignis nicht ausgelöst wird, wenn der Wert gesetzt wird.
var exposureCompensationControl = _mediaCapture.VideoDeviceController.ExposureCompensationControl;
if (exposureCompensationControl.Supported)
{
EvSlider.Visibility = Visibility.Visible;
EvSlider.Minimum = exposureCompensationControl.Min;
EvSlider.Maximum = exposureCompensationControl.Max;
EvSlider.StepFrequency = exposureCompensationControl.Step;
EvSlider.ValueChanged -= EvSlider_ValueChanged;
EvSlider.Value = exposureCompensationControl.Value;
EvSlider.ValueChanged += EvSlider_ValueChanged;
}
else
{
EvSlider.Visibility = Visibility.Collapsed;
}
Holen Sie sich im ValueChanged-Ereignishandler den aktuellen Wert des Steuerelements und setzen Sie den Belichtungswert durch den Aufruf SetValueAsync.
private async void EvSlider_ValueChanged(object sender, Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
{
var value = (sender as Slider).Value;
await _mediaCapture.VideoDeviceController.ExposureCompensationControl.SetValueAsync((float)value);
}
Flash (Blitzlicht)
Mit FlashControl können Sie den Blitz aktivieren oder deaktivieren oder den automatischen Blitz aktivieren, bei dem das System dynamisch bestimmt, ob der Blitz verwendet werden soll. Mit diesem Steuerelement können Sie auch die automatische Rote-Augen-Reduzierung auf Geräten aktivieren, die diese Funktion unterstützen. Diese Einstellungen gelten alle für die Aufnahme von Fotos. Die TorchControl ist eine separate Steuerung zum Ein- und Ausschalten der Taschenlampe für die Videoaufnahme.
In diesem Beispiel wird eine Reihe von Optionsschaltflächen verwendet, mit denen der Benutzer zwischen den Einstellungen „Ein", „Aus“ und „Automatischer Blitz“ wechseln kann. Außerdem gibt es ein Kontrollkästchen, mit dem sich die Reduzierung des Rote-Augen-Effekts und die Videotaschenlampe ein- und ausschalten lassen.
<RadioButton Name="FlashOnRadioButton" Content="On" Checked="FlashOnRadioButton_Checked"/>
<RadioButton Name="FlashAutoRadioButton" Content="Auto" Checked="FlashAutoRadioButton_Checked"/>
<RadioButton Name="FlashOffRadioButton" Content="Off" Checked="FlashOffRadioButton_Checked"/>
<CheckBox Name="RedEyeFlashCheckBox" Content="Red Eye" Visibility="Collapsed" Checked="RedEyeFlashCheckBox_CheckedChanged" Unchecked="RedEyeFlashCheckBox_CheckedChanged"/>
<CheckBox Name="TorchCheckBox" Content="Video Light" Visibility="Collapsed" Checked="TorchCheckBox_CheckedChanged" Unchecked="TorchCheckBox_CheckedChanged"/>
Überprüfen Sie, ob das aktuelle Erfassungsgerät FlashControl unterstützt, indem Sie die Eigenschaft Unterstützt überprüfen. Wenn das Steuerelement unterstützt wird, können Sie die Benutzeroberfläche für diese Funktion anzeigen und aktivieren. Wenn FlashControl unterstützt wird, kann die automatische Rote-Augen-Reduzierung unterstützt oder nicht unterstützt werden. Überprüfen Sie daher die Eigenschaft RedEyeReductionSupported bevor Sie die Benutzeroberfläche aktivieren. Da das TorchControl vom Blitzlicht-Steuerelement getrennt ist, müssen Sie auch dessen Eigenschaft Unterstützt überprüfen, bevor Sie es verwenden.
Aktivieren bzw. deaktivieren Sie im Ereignishandler Checked für jedes der Flash-Radio-Buttons die entsprechende Flash-Einstellung. Damit der Blitz immer verwendet wird, müssen Sie die Eigenschaft Enabled auf true und die Eigenschaft Auto auf false setzen.
var flashControl = _mediaCapture.VideoDeviceController.FlashControl;
if (flashControl.Supported)
{
FlashAutoRadioButton.Visibility = Visibility.Visible;
FlashOnRadioButton.Visibility = Visibility.Visible;
FlashOffRadioButton.Visibility = Visibility.Visible;
FlashAutoRadioButton.IsChecked = true;
if (flashControl.RedEyeReductionSupported)
{
RedEyeFlashCheckBox.Visibility = Visibility.Visible;
}
// Video light is not strictly part of flash, but users might expect to find it there
if (_mediaCapture.VideoDeviceController.TorchControl.Supported)
{
TorchCheckBox.Visibility = Visibility.Visible;
}
}
else
{
FlashAutoRadioButton.Visibility = Visibility.Collapsed;
FlashOnRadioButton.Visibility = Visibility.Collapsed;
FlashOffRadioButton.Visibility = Visibility.Collapsed;
}
private void FlashOnRadioButton_Checked(object sender, RoutedEventArgs e)
{
_mediaCapture.VideoDeviceController.FlashControl.Enabled = true;
_mediaCapture.VideoDeviceController.FlashControl.Auto = false;
}
private void FlashAutoRadioButton_Checked(object sender, RoutedEventArgs e)
{
_mediaCapture.VideoDeviceController.FlashControl.Enabled = true;
_mediaCapture.VideoDeviceController.FlashControl.Auto = true;
}
private void FlashOffRadioButton_Checked(object sender, RoutedEventArgs e)
{
_mediaCapture.VideoDeviceController.FlashControl.Enabled = false;
}
Setzen Sie im Handler für das Kontrollkästchen „Rote-Augen-Reduzierung“ die Eigenschaft RedEyeReduction auf den entsprechenden Wert.
private void RedEyeFlashCheckBox_CheckedChanged(object sender, RoutedEventArgs e)
{
_mediaCapture.VideoDeviceController.FlashControl.RedEyeReduction = (RedEyeFlashCheckBox.IsChecked == true);
}
Setzen Sie schließlich im Handler für das Kontrollkästchen der Videotaschenlampe die Eigenschaft Enabled auf den entsprechenden Wert.
private void TorchCheckBox_CheckedChanged(object sender, RoutedEventArgs e)
{
_mediaCapture.VideoDeviceController.TorchControl.Enabled = (TorchCheckBox.IsChecked == true);
if(! (_isPreviewing && _isRecording))
{
System.Diagnostics.Debug.WriteLine("Torch may not emit light if preview and video capture are not running.");
}
}
Hinweis
Auf einigen Geräten leuchtet die Taschenlampe nicht, selbst wenn TorchControl.Enabled auf true gesetzt ist, es sei denn, auf dem Gerät läuft ein Vorschaustream und es werden aktiv Videos aufgenommen. Die empfohlene Reihenfolge ist, die Videovorschau zu aktivieren, den Brenner einzuschalten, indem Sie Enabled auf true setzen, und dann die Videoaufnahme zu starten. Bei einigen Geräten leuchtet die Taschenlampe auf, nachdem die Vorschau gestartet wurde. Bei anderen Geräten leuchtet die Taschenlampe möglicherweise erst auf, wenn die Videoaufnahme gestartet wird.
Fokus
Das Objekt FocusControl unterstützt drei verschiedene, häufig verwendete Methoden zur Einstellung der Schärfe der Kamera: kontinuierlicher Autofokus, Tippen auf den Fokus und manueller Fokus. Eine Kamera-App kann alle drei dieser Methoden unterstützen. Aus Gründen der Lesbarkeit wird in diesem Artikel jedoch jede Technik einzeln behandelt. In diesem Abschnitt wird auch beschrieben, wie Sie das Fokus-Hilfslicht aktivieren.
Kontinuierlicher Autofokus
Wenn Sie den kontinuierlichen Autofokus aktivieren, wird die Kamera angewiesen, den Fokus dynamisch anzupassen, um zu versuchen, das Foto- oder Videomotiv im Fokus zu halten. In diesem Beispiel wird ein Optionsfeld verwendet, um den kontinuierlichen Autofokus ein- und auszuschalten.
<RadioButton Content="CAF" Name="CafFocusRadioButton" Checked="CafFocusRadioButton_Checked"/>
Überprüfen Sie, ob das aktuelle Erfassungsgerät FocusControl unterstützt, indem Sie die Eigenschaft Unterstützt überprüfen. Als Nächstes stellen Sie fest, ob der kontinuierliche Autofokus unterstützt wird, indem Sie in der Liste SupportedFocusModes prüfen, ob sie den Wert FocusMode.Continuous enthält, und wenn ja, die Optionsschaltfläche für den kontinuierlichen Autofokus anzeigen.
var focusControl = _mediaCapture.VideoDeviceController.FocusControl;
if (focusControl.Supported)
{
CafFocusRadioButton.Visibility = focusControl.SupportedFocusModes.Contains(FocusMode.Continuous)
? Visibility.Visible : Visibility.Collapsed;
}
else
{
CafFocusRadioButton.Visibility = Visibility.Collapsed;
}
Verwenden Sie im Ereignishandler Checked für die Optionsschaltfläche für den kontinuierlichen Autofokus die Eigenschaft VideoDeviceController.FocusControl, um eine Instanz des Steuerelements abzurufen. Rufen Sie UnlockAsync auf, um das Steuerelement zu entsperren, falls Ihre Anwendung zuvor LockAsync aufgerufen hat, um einen der anderen Fokusmodi zu aktivieren.
Erstellen Sie ein neues FocusSettings-Objekt und setzen Sie die Eigenschaft Mode auf Continuous. Setzen Sie die Eigenschaft AutoFocusRange auf einen Wert, der für Ihr Anwendungsszenario geeignet ist oder vom Benutzer über Ihre Benutzeroberfläche ausgewählt wird. Übergeben Sie Ihr FocusSettings-Objekt an die Configure-Methode, und rufen Sie dann FocusAsync auf, um den kontinuierlichen Autofokus zu starten.
private async void CafFocusRadioButton_Checked(object sender, RoutedEventArgs e)
{
if(! _isPreviewing)
{
// Autofocus only supported while preview stream is running.
return;
}
var focusControl = _mediaCapture.VideoDeviceController.FocusControl;
await focusControl.UnlockAsync();
var settings = new FocusSettings { Mode = FocusMode.Continuous, AutoFocusRange = AutoFocusRange.FullRange };
focusControl.Configure(settings);
await focusControl.FocusAsync();
}
Wichtig
Der Autofokusmodus wird nur unterstützt, während der Vorschaustream läuft. Vergewissern Sie sich, dass der Vorschaustream läuft, bevor Sie den kontinuierlichen Autofokus aktivieren.
Zum Fokussieren antippen
Die Tap-to-Focus-Technik verwendet das FocusControl und das RegionsOfInterestControl, um einen Teilbereich des Capture-Frames festzulegen, auf den das Capture-Gerät fokussieren soll. Der Fokusbereich wird bestimmt, indem der Benutzer auf den Bildschirm tippt, der den Vorschaustream anzeigt.
In diesem Beispiel wird ein Optionsfeld zum Aktivieren und Deaktivieren des Tap-to-Focus-Modus verwendet.
<RadioButton Content="Tap" Name="TapFocusRadioButton" Checked="TapFocusRadioButton_Checked"/>
Überprüfen Sie, ob das aktuelle Erfassungsgerät FocusControl unterstützt, indem Sie die Eigenschaft Unterstützt überprüfen. Die Website RegionsOfInterestControl muss unterstützt werden, und zwar mindestens eine Region, um diese Technik anwenden zu können. Überprüfen Sie die Eigenschaften AutoFocusSupported und MaxRegions, um festzulegen, ob das Optionsfeld für Tap-to-Focus angezeigt oder ausgeblendet werden soll.
var focusControl = _mediaCapture.VideoDeviceController.FocusControl;
if (focusControl.Supported)
{
TapFocusRadioButton.Visibility = (_mediaCapture.VideoDeviceController.RegionsOfInterestControl.AutoFocusSupported &&
_mediaCapture.VideoDeviceController.RegionsOfInterestControl.MaxRegions > 0)
? Visibility.Visible : Visibility.Collapsed;
}
else
{
TapFocusRadioButton.Visibility = Visibility.Collapsed;
}
Verwenden Sie im Checked-Ereignishandler für die Schaltfläche „Tap-to-Focus“ die Eigenschaft VideoDeviceController.FocusControl, um eine Instanz des Steuerelements abzurufen. Rufen Sie LockAsync auf, um das Steuerelement zu sperren, falls Ihre App zuvor UnlockAsync aufgerufen hat, um den kontinuierlichen Autofokus zu aktivieren, und warten Sie dann, bis der Benutzer auf den Bildschirm tippt, um den Fokus zu ändern.
private async void TapFocusRadioButton_Checked(object sender, RoutedEventArgs e)
{
// Lock focus in case Continuous Autofocus was active when switching to Tap-to-focus
var focusControl = _mediaCapture.VideoDeviceController.FocusControl;
await focusControl.LockAsync();
// Wait for user tap
}
In diesem Beispiel wird ein Bereich fokussiert, wenn der Benutzer auf den Bildschirm tippt, und der Fokus von diesem Bereich entfernt, wenn der Benutzer erneut tippt, wie bei einem Toggle. Verwenden Sie eine boolesche Variable, um den aktuellen Umschaltzustand zu verfolgen.
bool _isFocused = false;
Der nächste Schritt besteht darin, auf das Ereignis zu warten, wenn der Benutzer auf den Bildschirm tippt, indem das Ereignis Tapped des CaptureElements behandelt wird, das gerade den Vorschaustream anzeigt. Wenn die Kamera gerade keine Vorschau anzeigt oder der Tap-to-Focus-Modus deaktiviert ist, kehren Sie vom Handler zurück, ohne etwas zu tun.
Wenn die Tracking-Variable _isFocused auf false gesetzt ist und die Kamera nicht gerade fokussiert wird (was durch die Eigenschaft FocusState des FocusControl bestimmt wird), beginnt der Tap-to-Focus-Prozess. Ermittelt die Position des Benutzertaps aus den Ereignis-Args, die an den Handler übergeben wurden. In diesem Beispiel wird diese Gelegenheit auch genutzt, um die Größe der Region zu bestimmen, auf die der Schwerpunkt gelegt werden soll. In diesem Fall beträgt die Größe 1/4 der kleinsten Abmessung des Fangelements. Übergeben Sie die Tap-Position und die Größe des Bereichs an die Hilfsmethode TapToFocus, die im nächsten Abschnitt definiert ist.
Wenn der Toggle _isFocused auf true gesetzt ist, sollte der Benutzertipp den Fokus vom vorherigen Bereich löschen. Dies geschieht in der unten gezeigten Hilfsmethode TapUnfocus.
private async void PreviewControl_Tapped(object sender, TappedRoutedEventArgs e)
{
if (!_isPreviewing || (TapFocusRadioButton.IsChecked != true)) return;
if (!_isFocused && _mediaCapture.VideoDeviceController.FocusControl.FocusState != MediaCaptureFocusState.Searching)
{
var smallEdge = Math.Min(Window.Current.Bounds.Width, Window.Current.Bounds.Height);
// Choose to make the focus rectangle 1/4th the length of the shortest edge of the window
var size = new Size(smallEdge / 4, smallEdge / 4);
var position = e.GetPosition(sender as UIElement);
// Note that at this point, a rect at "position" with size "size" could extend beyond the preview area. The following method will reposition the rect if that is the case
await TapToFocus(position, size);
}
else
{
await TapUnfocus();
}
}
Setzen Sie in der Hilfsmethode TapToFocus zunächst den Schalter _isFocused auf true, damit beim nächsten Antippen des Bildschirms der Fokus aus dem angetippten Bereich freigegeben wird.
Die nächste Aufgabe in dieser Hilfsmethode besteht darin, das Rechteck innerhalb des Vorschaustreams zu bestimmen, das dem Fokus-Steuerelement zugewiesen werden soll. Dies erfordert zwei Schritte. Der erste Schritt besteht darin, das Rechteck zu bestimmen, das der Vorschaustream innerhalb des Steuerelements CaptureElement einnimmt. Dies hängt von den Abmessungen des Vorschaustreams und der Ausrichtung des Geräts ab. Die Hilfsmethode GetPreviewStreamRectInControl, die am Ende dieses Abschnitts gezeigt wird, führt diese Aufgabe aus und gibt das Rechteck zurück, das den Vorschaustream enthält.
Die nächste Aufgabe in TapToFocus besteht darin, die Tap-Position und die gewünschte Größe des Fokus-Rechtecks, die im CaptureElement.Tapped Ereignishandler bestimmt wurden, in Koordinaten im Capture-Stream umzuwandeln. Die Hilfsmethode ConvertUiTapToPreviewRect, die später in diesem Abschnitt gezeigt wird, führt diese Umwandlung durch und gibt das Rechteck in den Koordinaten des Capture-Streams zurück, in dem der Fokus angefordert wird.
Nachdem Sie nun das Zielrechteck ermittelt haben, erstellen Sie ein neues RegionOfInterest-Objekt und setzen die Eigenschaft Bounds auf das in den vorherigen Schritten ermittelte Zielrechteck.
Holen Sie sich das Aufnahmegerät FocusControl. Erstellen Sie ein neues FocusSettings-Objekt und setzen Sie die Mode und AutoFocusRange auf die gewünschten Werte, nachdem Sie überprüft haben, ob diese von der FocusControl unterstützt werden. Rufen Sie Configure auf dem FocusControl auf, um Ihre Einstellungen zu aktivieren und dem Gerät zu signalisieren, mit der Fokussierung auf den angegebenen Bereich zu beginnen.
Als nächstes rufen Sie RegionsOfInterestControl des Erfassungsgeräts ab und rufen SetRegionsAsync auf, um die aktive Region festzulegen. Auf Geräten, die dies unterstützen, können mehrere Regionen von Interesse festgelegt werden, aber in diesem Beispiel wird nur eine einzige Region festgelegt.
Rufen Sie schließlich FocusAsync auf FocusControl auf, um die Fokussierung einzuleiten.
Wichtig
Bei der Implementierung von Tap to Focus ist die Reihenfolge der Vorgänge wichtig. Sie sollten diese APIs in der folgenden Reihenfolge aufrufen:
public async Task TapToFocus(Point position, Size size)
{
_isFocused = true;
var previewRect = GetPreviewStreamRectInControl();
var focusPreview = ConvertUiTapToPreviewRect(position, size, previewRect);
// Note that this Region Of Interest could be configured to also calculate exposure
// and white balance within the region
var regionOfInterest = new RegionOfInterest
{
AutoFocusEnabled = true,
BoundsNormalized = true,
Bounds = focusPreview,
Type = RegionOfInterestType.Unknown,
Weight = 100,
};
var focusControl = _mediaCapture.VideoDeviceController.FocusControl;
var focusRange = focusControl.SupportedFocusRanges.Contains(AutoFocusRange.FullRange) ? AutoFocusRange.FullRange : focusControl.SupportedFocusRanges.FirstOrDefault();
var focusMode = focusControl.SupportedFocusModes.Contains(FocusMode.Single) ? FocusMode.Single : focusControl.SupportedFocusModes.FirstOrDefault();
var settings = new FocusSettings { Mode = focusMode, AutoFocusRange = focusRange };
focusControl.Configure(settings);
var roiControl = _mediaCapture.VideoDeviceController.RegionsOfInterestControl;
await roiControl.SetRegionsAsync(new[] { regionOfInterest }, true);
await focusControl.FocusAsync();
}
Holen Sie sich in der Hilfsmethode TapUnfocus das RegionsOfInterestControl und rufen Sie ClearRegionsAsync auf, um die Region zu löschen, die mit dem Steuerelement in der Hilfsmethode TapToFocus registriert wurde. Holen Sie sich dann das FocusControl und rufen Sie FocusAsync auf, um das Gerät zu veranlassen, den Fokus ohne einen Bereich von Interesse neu zu setzen.
private async Task TapUnfocus()
{
_isFocused = false;
var roiControl = _mediaCapture.VideoDeviceController.RegionsOfInterestControl;
await roiControl.ClearRegionsAsync();
var focusControl = _mediaCapture.VideoDeviceController.FocusControl;
await focusControl.FocusAsync();
}
Die Hilfsmethode GetPreviewStreamRectInControl verwendet die Auflösung des Vorschaustreams und die Ausrichtung des Geräts, um das Rechteck innerhalb des Vorschauelements zu bestimmen, das den Vorschaustream enthält, und schneidet dabei alle Letterbox-Paddings ab, die das Steuerelement zur Beibehaltung des Seitenverhältnisses des Streams bereitstellen kann. Diese Methode verwendet Klassenvariablen, die im grundlegenden Beispielcode für die Medienerfassung unter Basic photo, video, and audio capture with MediaCapture definiert sind.
public Rect GetPreviewStreamRectInControl()
{
var result = new Rect();
var previewResolution = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties;
// In case this function is called before everything is initialized correctly, return an empty result
if (PreviewControl == null || PreviewControl.ActualHeight < 1 || PreviewControl.ActualWidth < 1 ||
previewResolution == null || previewResolution.Height == 0 || previewResolution.Width == 0)
{
return result;
}
var streamWidth = previewResolution.Width;
var streamHeight = previewResolution.Height;
// For portrait orientations, the width and height need to be swapped
if (_displayOrientation == DisplayOrientations.Portrait || _displayOrientation == DisplayOrientations.PortraitFlipped)
{
streamWidth = previewResolution.Height;
streamHeight = previewResolution.Width;
}
// Start by assuming the preview display area in the control spans the entire width and height both (this is corrected in the next if for the necessary dimension)
result.Width = PreviewControl.ActualWidth;
result.Height = PreviewControl.ActualHeight;
// If UI is "wider" than preview, letterboxing will be on the sides
if ((PreviewControl.ActualWidth / PreviewControl.ActualHeight > streamWidth / (double)streamHeight))
{
var scale = PreviewControl.ActualHeight / streamHeight;
var scaledWidth = streamWidth * scale;
result.X = (PreviewControl.ActualWidth - scaledWidth) / 2.0;
result.Width = scaledWidth;
}
else // Preview stream is "wider" than UI, so letterboxing will be on the top+bottom
{
var scale = PreviewControl.ActualWidth / streamWidth;
var scaledHeight = streamHeight * scale;
result.Y = (PreviewControl.ActualHeight - scaledHeight) / 2.0;
result.Height = scaledHeight;
}
return result;
}
Die Hilfsmethode ConvertUiTapToPreviewRect nimmt als Argumente den Ort des Tap-Ereignisses, die gewünschte Größe des Fokusbereichs und das Rechteck, das den Vorschaustream enthält, der von der Hilfsmethode GetPreviewStreamRectInControl erhalten wurde. Diese Methode verwendet diese Werte und die aktuelle Ausrichtung des Geräts, um das Rechteck im Vorschaustream zu berechnen, das den gewünschten Bereich enthält. Auch diese Methode verwendet Klassenvariablen, die im grundlegenden Beispielcode für die Medienerfassung unter Capture Photos and Video with MediaCapture definiert sind.
private Rect ConvertUiTapToPreviewRect(Point tap, Size size, Rect previewRect)
{
// Adjust for the resulting focus rectangle to be centered around the position
double left = tap.X - size.Width / 2, top = tap.Y - size.Height / 2;
// Get the information about the active preview area within the CaptureElement (in case it's letterboxed)
double previewWidth = previewRect.Width, previewHeight = previewRect.Height;
double previewLeft = previewRect.Left, previewTop = previewRect.Top;
// Transform the left and top of the tap to account for rotation
switch (_displayOrientation)
{
case DisplayOrientations.Portrait:
var tempLeft = left;
left = top;
top = previewRect.Width - tempLeft;
break;
case DisplayOrientations.LandscapeFlipped:
left = previewRect.Width - left;
top = previewRect.Height - top;
break;
case DisplayOrientations.PortraitFlipped:
var tempTop = top;
top = left;
left = previewRect.Width - tempTop;
break;
}
// For portrait orientations, the information about the active preview area needs to be rotated
if (_displayOrientation == DisplayOrientations.Portrait || _displayOrientation == DisplayOrientations.PortraitFlipped)
{
previewWidth = previewRect.Height;
previewHeight = previewRect.Width;
previewLeft = previewRect.Top;
previewTop = previewRect.Left;
}
// Normalize width and height of the focus rectangle
var width = size.Width / previewWidth;
var height = size.Height / previewHeight;
// Shift rect left and top to be relative to just the active preview area
left -= previewLeft;
top -= previewTop;
// Normalize left and top
left /= previewWidth;
top /= previewHeight;
// Ensure rectangle is fully contained within the active preview area horizontally
left = Math.Max(left, 0);
left = Math.Min(1 - width, left);
// Ensure rectangle is fully contained within the active preview area vertically
top = Math.Max(top, 0);
top = Math.Min(1 - height, top);
// Create and return resulting rectangle
return new Rect(left, top, width, height);
}
Manueller Fokus
Bei der manuellen Fokussierung wird mit dem Schieberegler die aktuelle Schärfentiefe des Aufnahmegeräts eingestellt. Mit einer Optionsschaltfläche können Sie den manuellen Fokus ein- und ausschalten.
<Slider Name="FocusSlider" IsEnabled="{Binding ElementName=ManualFocusRadioButton,Path=IsChecked}" ValueChanged="FocusSlider_ValueChanged"/>
<TextBlock Text="{Binding ElementName=FocusSlider,Path=Value,FallbackValue='0'}"/>
<RadioButton Content="Manual" Name="ManualFocusRadioButton" Checked="ManualFocusRadioButton_Checked" IsChecked="False"/>
Überprüfen Sie, ob das aktuelle Erfassungsgerät FocusControl unterstützt, indem Sie die Eigenschaft Unterstützt überprüfen. Wenn das Steuerelement unterstützt wird, können Sie die Benutzeroberfläche für diese Funktion anzeigen und aktivieren.
Der Fokuswert muss innerhalb des vom Gerät unterstützten Bereichs liegen und ein Inkrement der unterstützten Schrittweite sein. Rufen Sie die unterstützten Werte für das aktuelle Gerät ab, indem Sie die Eigenschaften Min, Max und Step überprüfen, die zum Festlegen der entsprechenden Eigenschaften des Schieberegler-Steuerelements verwendet werden.
Setzen Sie den Wert des Schieberegler-Steuerelements auf den aktuellen Wert des FocusControl, nachdem Sie die Registrierung des ValueChanged-Ereignishandlers aufgehoben haben, damit das Ereignis nicht ausgelöst wird, wenn der Wert gesetzt wird.
var focusControl = _mediaCapture.VideoDeviceController.FocusControl;
if (focusControl.Supported)
{
FocusSlider.Visibility = Visibility.Visible;
ManualFocusRadioButton.Visibility = Visibility.Visible;
FocusSlider.Minimum = focusControl.Min;
FocusSlider.Maximum = focusControl.Max;
FocusSlider.StepFrequency = focusControl.Step;
FocusSlider.ValueChanged -= FocusSlider_ValueChanged;
FocusSlider.Value = focusControl.Value;
FocusSlider.ValueChanged += FocusSlider_ValueChanged;
}
else
{
FocusSlider.Visibility = Visibility.Collapsed;
ManualFocusRadioButton.Visibility = Visibility.Collapsed;
}
Holen Sie sich im Checked-Ereignishandler für das manuelle Fokus-Radio-Button das FocusControl-Objekt und rufen Sie LockAsync auf, falls Ihre App zuvor den Fokus mit einem Aufruf von UnlockAsync entsperrt hat.
private async void ManualFocusRadioButton_Checked(object sender, RoutedEventArgs e)
{
var focusControl = _mediaCapture.VideoDeviceController.FocusControl;
await focusControl.LockAsync();
}
Im ValueChanged Ereignishandler des manuellen Fokus-Sliders holen Sie sich den aktuellen Wert des Controls und setzen den Fokuswert durch den Aufruf SetValueAsync.
private async void FocusSlider_ValueChanged(object sender, Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
{
var value = (sender as Slider).Value;
await _mediaCapture.VideoDeviceController.FocusControl.SetValueAsync((uint)value);
}
Aktivieren Sie das Fokuslicht
Bei Geräten, die diese Funktion unterstützen, können Sie ein Fokus-Hilfslicht aktivieren, um die Scharfstellung des Geräts zu unterstützen. In diesem Beispiel wird ein Kontrollkästchen zum Aktivieren oder Deaktivieren des Fokusassistenten verwendet.
<CheckBox Content="Assist Light" Name="FocusLightCheckBox" IsEnabled="{Binding ElementName=TapFocusRadioButton,Path=IsChecked}"
Checked="FocusLightCheckBox_CheckedChanged" Unchecked="FocusLightCheckBox_CheckedChanged"/>
Überprüfen Sie, ob das aktuelle Erfassungsgerät FlashControl unterstützt, indem Sie die Eigenschaft Unterstützt überprüfen. Überprüfen Sie auch die AssistantLightSupported, um sicherzustellen, dass das Hilfslicht ebenfalls unterstützt wird. Wenn beide unterstützt werden, können Sie die Benutzeroberfläche für diese Funktion anzeigen und aktivieren.
var focusControl = _mediaCapture.VideoDeviceController.FocusControl;
if (focusControl.Supported)
{
FocusLightCheckBox.Visibility = (_mediaCapture.VideoDeviceController.FlashControl.Supported &&
_mediaCapture.VideoDeviceController.FlashControl.AssistantLightSupported) ? Visibility.Visible : Visibility.Collapsed;
}
else
{
FocusLightCheckBox.Visibility = Visibility.Collapsed;
}
Holen Sie sich im Ereignishandler CheckedChanged das Objekt FlashControl der Erfassungsgeräte. Legen Sie die Eigenschaft AssistantLightEnabled fest, um das Fokuslicht zu aktivieren oder zu deaktivieren.
private void FocusLightCheckBox_CheckedChanged(object sender, RoutedEventArgs e)
{
var flashControl = _mediaCapture.VideoDeviceController.FlashControl;
flashControl.AssistantLightEnabled = (FocusLightCheckBox.IsChecked == true);
}
ISO-Geschwindigkeit
Mit IsoSpeedControl können Sie die ISO-Empfindlichkeit für die Foto- oder Videoaufnahme einstellen.
In diesem Beispiel wird ein Schieberegler verwendet, um den aktuellen Belichtungskorrekturwert einzustellen, und ein Kontrollkästchen, um die automatische Anpassung der ISO-Empfindlichkeit zu aktivieren.
<Slider Name="IsoSlider" ValueChanged="IsoSlider_ValueChanged"/>
<TextBlock Text="{Binding ElementName=IsoSlider,Path=Value}" Visibility="{Binding ElementName=IsoSlider,Path=Visibility}"/>
<CheckBox Name="IsoAutoCheckBox" Content="Auto" Checked="IsoAutoCheckBox_CheckedChanged" Unchecked="IsoAutoCheckBox_CheckedChanged"/>
Prüfen Sie, ob das aktuelle Erfassungsgerät IsoSpeedControl unterstützt, indem Sie die Eigenschaft Unterstützt überprüfen. Wenn das Steuerelement unterstützt wird, können Sie die Benutzeroberfläche für diese Funktion anzeigen und aktivieren. Setzen Sie den Status des Kontrollkästchens, das anzeigt, ob die automatische Anpassung der ISO-Empfindlichkeit derzeit aktiv ist, auf den Wert der Eigenschaft Auto.
Der ISO-Geschwindigkeitswert muss innerhalb des vom Gerät unterstützten Bereichs liegen und ein Inkrement der unterstützten Schrittweite sein. Rufen Sie die unterstützten Werte für das aktuelle Gerät ab, indem Sie die Eigenschaften Min, Max und Step überprüfen, die zum Festlegen der entsprechenden Eigenschaften des Schieberegler-Steuerelements verwendet werden.
Setzen Sie den Wert des Schieberegler-Steuerelements auf den aktuellen Wert des IsoSpeedControl, nachdem Sie die Registrierung des ValueChanged-Ereignishandlers aufgehoben haben, damit das Ereignis nicht ausgelöst wird, wenn der Wert gesetzt wird.
private void UpdateIsoControlCapabilities()
{
var isoSpeedControl = _mediaCapture.VideoDeviceController.IsoSpeedControl;
if (isoSpeedControl.Supported)
{
IsoAutoCheckBox.Visibility = Visibility.Visible;
IsoSlider.Visibility = Visibility.Visible;
IsoAutoCheckBox.IsChecked = isoSpeedControl.Auto;
IsoSlider.Minimum = isoSpeedControl.Min;
IsoSlider.Maximum = isoSpeedControl.Max;
IsoSlider.StepFrequency = isoSpeedControl.Step;
IsoSlider.ValueChanged -= IsoSlider_ValueChanged;
IsoSlider.Value = isoSpeedControl.Value;
IsoSlider.ValueChanged += IsoSlider_ValueChanged;
}
else
{
IsoAutoCheckBox.Visibility = Visibility.Collapsed;
IsoSlider.Visibility = Visibility.Collapsed;
}
}
Holen Sie sich im ValueChanged-Ereignishandler den aktuellen Wert des Steuerelements und setzen Sie den ISO-Geschwindigkeitswert durch den Aufruf von SetValueAsync.
private async void IsoSlider_ValueChanged(object sender, Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
{
var value = (sender as Slider).Value;
await _mediaCapture.VideoDeviceController.IsoSpeedControl.SetValueAsync((uint)value);
}
Aktivieren Sie im Ereignishandler CheckedChanged des Kontrollkästchens für die automatische ISO-Geschwindigkeit die automatische Anpassung der ISO-Geschwindigkeit, indem Sie SetAutoAsync aufrufen. Deaktivieren Sie die automatische Anpassung der ISO-Geschwindigkeit, indem Sie SetValueAsync aufrufen und den aktuellen Wert des Schiebereglers übergeben.
private async void IsoAutoCheckBox_CheckedChanged(object sender, RoutedEventArgs e)
{
var autoIso = (sender as CheckBox).IsChecked == true;
if (autoIso)
{
await _mediaCapture.VideoDeviceController.IsoSpeedControl.SetAutoAsync();
}
else
{
await _mediaCapture.VideoDeviceController.IsoSpeedControl.SetValueAsync((uint)IsoSlider.Value);
}
}
Optische Bildstabilisierung
Die optische Bildstabilisierung (OIS) stabilisiert einen aufgenommenen Videostream durch mechanische Manipulation des Hardware-Aufnahmegeräts, was ein besseres Ergebnis als die digitale Stabilisierung liefern kann. Auf Geräten, die OIS nicht unterstützen, können Sie die VideoStabilizationEffect verwenden, um die digitale Stabilisierung ihres aufgenommenen Videos durchzuführen. Weitere Informationen finden Sie unter Effekte für Videoaufnahmen.
Ermitteln Sie, ob OIS auf dem aktuellen Gerät unterstützt wird, indem Sie die Eigenschaft OpticalImageStabilizationControl.Supported überprüfen.
Die OIS-Steuerung unterstützt drei Modi: Ein, Aus und Automatik, d. h. das Gerät ermittelt dynamisch, ob OIS die Medienaufnahme verbessern würde, und aktiviert OIS, wenn dies der Fall ist. Um festzustellen, ob ein bestimmter Modus auf einem Gerät unterstützt wird, prüfen Sie, ob die Sammlung OpticalImageStabilizationControl.SupportedModes den gewünschten Modus enthält.
Aktivieren oder deaktivieren Sie OIS, indem Sie den OpticalImageStabilizationControl.Mode auf den gewünschten Modus einstellen.
private void SetOpticalImageStabilizationMode(OpticalImageStabilizationMode mode)
{
if (!_mediaCapture.VideoDeviceController.OpticalImageStabilizationControl.Supported)
{
ShowMessageToUser("Optical image stabilization not available");
return;
}
var stabilizationModes = _mediaCapture.VideoDeviceController.OpticalImageStabilizationControl.SupportedModes;
if (!stabilizationModes.Contains(mode))
{
ShowMessageToUser("Optical image stabilization setting not supported");
return;
}
_mediaCapture.VideoDeviceController.OpticalImageStabilizationControl.Mode = mode;
}
Netzfrequenz
Einige Kamerageräte unterstützen eine Antiflicker-Verarbeitung, die von der Kenntnis der Wechselstromfrequenz der Stromleitungen in der aktuellen Umgebung abhängt. Einige Geräte unterstützen die automatische Bestimmung der Netzfrequenz, während bei anderen die Frequenz manuell eingestellt werden muss. Das folgende Code-Beispiel zeigt, wie die Powerline-Frequenzunterstützung auf dem Gerät ermittelt wird und wie die Frequenz bei Bedarf manuell eingestellt wird.
Rufen Sie zunächst die Methode VideoDeviceController TryGetPowerlineFrequency auf und übergeben Sie einen Ausgabeparameter vom Typ PowerlineFrequency; schlägt dieser Aufruf fehl, wird die Powerline-Frequenzsteuerung vom aktuellen Gerät nicht unterstützt. Wenn die Funktion unterstützt wird, können Sie feststellen, ob der automatische Modus auf dem Gerät verfügbar ist, indem Sie versuchen, den automatischen Modus einzustellen. Rufen Sie dazu TrySetPowerlineFrequency auf und übergeben Sie den Wert Auto. Wenn der Anruf erfolgreich ist, bedeutet dies, dass Ihre Auto-Powerline-Frequenz unterstützt wird. Wenn der Powerline-Frequenzregler auf dem Gerät unterstützt wird, aber die automatische Frequenzerkennung nicht, können Sie die Frequenz immer noch manuell einstellen, indem Sie TrySetPowerlineFrequency verwenden. In diesem Beispiel ist MyCustomFrequencyLookup eine benutzerdefinierte Methode, die Sie implementieren, um die richtige Frequenz für den aktuellen Standort des Geräts zu ermitteln.
PowerlineFrequency getFrequency;
if (! _mediaCapture.VideoDeviceController.TryGetPowerlineFrequency(out getFrequency))
{
// Powerline frequency is not supported on this device.
return;
}
if (! _mediaCapture.VideoDeviceController.TrySetPowerlineFrequency(PowerlineFrequency.Auto))
{
// Set the frequency manually
PowerlineFrequency setFrequency = MyCustomFrequencyLookup();
if (_mediaCapture.VideoDeviceController.TrySetPowerlineFrequency(setFrequency))
{
System.Diagnostics.Debug.WriteLine(String.Format("Powerline frequency manually set to {0}.", setFrequency));
}
}
Weißabgleich
Mit WhiteBalanceControl können Sie den Weißabgleich für die Foto- oder Videoaufnahme einstellen.
In diesem Beispiel wird ein ComboBox Steuerelement zur Auswahl aus den integrierten Farbtemperaturvoreinstellungen und ein Slider Steuerelement zur manuellen Einstellung des Weißabgleichs verwendet.
<Slider Name="WbSlider" ValueChanged="WbSlider_ValueChanged"/>
<TextBlock Name="WbTextBox" Text="{Binding ElementName=WbSlider,Path=Value}" Visibility="{Binding ElementName=WbSlider,Path=Visibility}"/>
<ComboBox Name="WbComboBox" SelectionChanged="WbComboBox_SelectionChanged"/>
Überprüfen Sie, ob das aktuelle Aufnahmegerät die WhiteBalanceControl unterstützt, indem Sie die Eigenschaft Unterstützt überprüfen. Wenn das Steuerelement unterstützt wird, können Sie die Benutzeroberfläche für diese Funktion anzeigen und aktivieren. Setzen Sie die Elemente des Kombinationsfeldes auf die Werte der Aufzählung ColorTemperaturePreset. Und setzen Sie das ausgewählte Element auf den aktuellen Wert der Eigenschaft Voreinstellung.
Bei der manuellen Steuerung muss der Weißabgleichswert innerhalb des vom Gerät unterstützten Bereichs liegen und eine Schrittweite der unterstützten Schrittgröße betragen. Rufen Sie die unterstützten Werte für das aktuelle Gerät ab, indem Sie die Eigenschaften Min, Max und Step überprüfen, die zum Festlegen der entsprechenden Eigenschaften des Schieberegler-Steuerelements verwendet werden. Bevor Sie die manuelle Steuerung aktivieren, vergewissern Sie sich, dass der Bereich zwischen den unterstützten Mindest- und Höchstwerten größer ist als die Schrittweite. Ist dies nicht der Fall, wird die manuelle Steuerung von dem aktuellen Gerät nicht unterstützt.
Setzen Sie den Wert des Schieberegler-Steuerelements auf den aktuellen Wert des WhiteBalanceControl, nachdem Sie die Registrierung des ValueChanged-Ereignishandlers aufgehoben haben, damit das Ereignis nicht ausgelöst wird, wenn der Wert gesetzt wird.
var whiteBalanceControl = _mediaCapture.VideoDeviceController.WhiteBalanceControl;
if (whiteBalanceControl.Supported)
{
WbSlider.Visibility = Visibility.Visible;
WbComboBox.Visibility = Visibility.Visible;
if (WbComboBox.ItemsSource == null)
{
WbComboBox.ItemsSource = Enum.GetValues(typeof(ColorTemperaturePreset)).Cast<ColorTemperaturePreset>();
}
WbComboBox.SelectedItem = whiteBalanceControl.Preset;
if (whiteBalanceControl.Max - whiteBalanceControl.Min > whiteBalanceControl.Step)
{
WbSlider.Minimum = whiteBalanceControl.Min;
WbSlider.Maximum = whiteBalanceControl.Max;
WbSlider.StepFrequency = whiteBalanceControl.Step;
WbSlider.ValueChanged -= WbSlider_ValueChanged;
WbSlider.Value = whiteBalanceControl.Value;
WbSlider.ValueChanged += WbSlider_ValueChanged;
}
else
{
WbSlider.Visibility = Visibility.Collapsed;
}
}
else
{
WbSlider.Visibility = Visibility.Collapsed;
WbComboBox.Visibility = Visibility.Collapsed;
}
Holen Sie sich im SelectionChanged-Ereignishandler des Farbtemperatur-Voreinstellungs-Kombinationsfeldes die aktuell ausgewählte Voreinstellung und setzen Sie den Wert des Steuerelements durch Aufruf von SetPresetAsync. Wenn der ausgewählte voreingestellte Wert nicht Manuell ist, deaktivieren Sie den Schieberegler für den manuellen Weißabgleich.
private async void WbComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if(!_isPreviewing)
{
// Do not set white balance values unless the preview stream is running.
return;
}
var selected = (ColorTemperaturePreset)WbComboBox.SelectedItem;
WbSlider.IsEnabled = (selected == ColorTemperaturePreset.Manual);
await _mediaCapture.VideoDeviceController.WhiteBalanceControl.SetPresetAsync(selected);
}
Holen Sie sich im ValueChanged-Ereignishandler den aktuellen Wert des Steuerelements und setzen Sie den Weißabgleichswert durch den Aufruf SetValueAsync.
private async void WbSlider_ValueChanged(object sender, Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
{
if (!_isPreviewing)
{
// Do not set white balance values unless the preview stream is running.
return;
}
var value = (sender as Slider).Value;
await _mediaCapture.VideoDeviceController.WhiteBalanceControl.SetValueAsync((uint)value);
}
Wichtig
Die Einstellung des Weißabgleichs wird nur unterstützt, während der Vorschaustream läuft. Vergewissern Sie sich, dass der Vorschaustream läuft, bevor Sie den Weißabgleichswert oder die Voreinstellung festlegen.
Wichtig
Der voreingestellte Wert ColorTemperaturePreset.Auto weist das System an, den Weißabgleich automatisch vorzunehmen. In einigen Fällen, z. B. bei der Aufnahme einer Fotosequenz, bei der die Weißabgleichswerte für jedes Bild gleich sein sollen, können Sie den Regler auf den aktuellen automatischen Wert festlegen. Rufen Sie dazu SetPresetAsync auf und geben Sie die Voreinstellung Manual an und setzen Sie keinen Wert auf das Steuerelement mit SetValueAsync. Dies führt dazu, dass das Gerät den aktuellen Wert sperrt. Versuchen Sie nicht, den aktuellen Kontrollwert zu lesen und dann den zurückgegebenen Wert an SetValueAsync zu übergeben, da dieser Wert nicht garantiert korrekt ist.
Zoom
Mit ZoomControl können Sie die Zoomstufe einstellen, die bei der Foto- oder Videoaufnahme verwendet wird.
In diesem Beispiel wird ein Slider-Steuerelement verwendet, um die aktuelle Zoomstufe einzustellen. Im folgenden Abschnitt wird gezeigt, wie Sie den Zoom auf der Grundlage einer Pinch-Geste auf dem Bildschirm anpassen können.
<Slider Name="ZoomSlider" Grid.Row="0" Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Stretch" ValueChanged="ZoomSlider_ValueChanged"/>
<TextBlock Grid.Row="1" HorizontalAlignment="Center" Text="{Binding ElementName=ZoomSlider,Path=Value}"/>
Überprüfen Sie, ob das aktuelle Aufnahmegerät ZoomControl unterstützt, indem Sie die Eigenschaft Unterstützt überprüfen. Wenn das Steuerelement unterstützt wird, können Sie die Benutzeroberfläche für diese Funktion anzeigen und aktivieren.
Der Wert der Zoomstufe muss innerhalb des vom Gerät unterstützten Bereichs liegen und ein Inkrement der unterstützten Schrittweite sein. Rufen Sie die unterstützten Werte für das aktuelle Gerät ab, indem Sie die Eigenschaften Min, Max und Step überprüfen, die zum Festlegen der entsprechenden Eigenschaften des Schieberegler-Steuerelements verwendet werden.
Setzen Sie den Wert des Schieberegler-Steuerelements auf den aktuellen Wert des ZoomControl, nachdem Sie die Registrierung des ValueChanged-Ereignishandlers aufgehoben haben, damit das Ereignis nicht ausgelöst wird, wenn der Wert gesetzt wird.
var zoomControl = _mediaCapture.VideoDeviceController.ZoomControl;
if (zoomControl.Supported)
{
ZoomSlider.Visibility = Visibility.Visible;
ZoomSlider.Minimum = zoomControl.Min;
ZoomSlider.Maximum = zoomControl.Max;
ZoomSlider.StepFrequency = zoomControl.Step;
ZoomSlider.ValueChanged -= ZoomSlider_ValueChanged;
ZoomSlider.Value = zoomControl.Value;
ZoomSlider.ValueChanged += ZoomSlider_ValueChanged;
}
else
{
ZoomSlider.Visibility = Visibility.Collapsed;
}
Erstellen Sie im Ereignishandler ValueChanged eine neue Instanz der Klasse ZoomSettings und setzen Sie die Eigenschaft Value auf den aktuellen Wert des Zoom-Schiebereglers. Wenn die Eigenschaft SupportedModes des ZoomControl den Wert ZoomTransitionMode.Smooth enthält, bedeutet dies, dass das Gerät weiche Übergänge zwischen den Zoomstufen unterstützt. Da dieser Modus eine bessere Benutzererfahrung bietet, werden Sie normalerweise diesen Wert für die Eigenschaft Mode des ZoomSettings-Objekts verwenden wollen.
Ändern Sie schließlich die aktuellen Zoomeinstellungen, indem Sie Ihr ZoomSettings-Objekt an die Configure-Methode des ZoomControl-Objekts übergeben.
private void ZoomSlider_ValueChanged(object sender, Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
{
var level = (float)ZoomSlider.Value;
var settings = new ZoomSettings { Value = level };
var zoomControl = _mediaCapture.VideoDeviceController.ZoomControl;
if (zoomControl.SupportedModes.Contains(ZoomTransitionMode.Smooth))
{
settings.Mode = ZoomTransitionMode.Smooth;
}
else
{
settings.Mode = zoomControl.SupportedModes.First();
}
zoomControl.Configure(settings);
}
Smooth-Zoomen mit Pinch-Geste
Wie im vorangegangenen Abschnitt beschrieben, ermöglicht der Smooth-Zoom-Modus bei Geräten, die ihn unterstützen, dem Aufnahmegerät einen fließenden Übergang zwischen den digitalen Zoomstufen, so dass der Benutzer die Zoomstufe während der Aufnahme dynamisch und ohne diskrete und störende Übergänge anpassen kann. In diesem Abschnitt wird beschrieben, wie Sie die Zoomstufe als Reaktion auf eine Pinch-Geste anpassen können.
Stellen Sie zunächst fest, ob die digitale Zoomsteuerung auf dem aktuellen Gerät unterstützt wird, indem Sie die Eigenschaft ZoomControl.Supported überprüfen. Stellen Sie als Nächstes fest, ob der Smooth-Zoom-Modus verfügbar ist, indem Sie in ZoomControl.SupportedModes prüfen, ob er den Wert ZoomTransitionMode.Smooth enthält.
private bool IsSmoothZoomSupported()
{
if (!_mediaCapture.VideoDeviceController.ZoomControl.Supported)
{
ShowMessageToUser("Digital zoom is not supported on this device.");
return false;
}
var zoomModes = _mediaCapture.VideoDeviceController.ZoomControl.SupportedModes;
if (!zoomModes.Contains(ZoomTransitionMode.Smooth))
{
ShowMessageToUser("Smooth zoom not supported");
return false;
}
return true;
}
Auf einem Multi-Touch-fähigen Gerät ist ein typisches Szenario die Anpassung des Zoomfaktors auf der Grundlage einer Zwei-Finger-Bedienungsgeste. Setzen Sie die Eigenschaft ManipulationMode des Steuerelements CaptureElement auf ManipulationModes.Scale, um die Pinch-Geste zu aktivieren. Registrieren Sie sich dann für das Ereignis ManipulationDelta, das ausgelöst wird, wenn sich die Größe der Pinch-Geste ändert.
private void RegisterPinchGestureHandler()
{
if (!IsSmoothZoomSupported())
{
return;
}
// Enable pinch/zoom gesture for the preview control
PreviewControl.ManipulationMode = ManipulationModes.Scale;
PreviewControl.ManipulationDelta += PreviewControl_ManipulationDelta;
}
Aktualisieren Sie im Handler für das Ereignis ManipulationDelta den Zoomfaktor basierend auf der Änderung der Pinch-Geste des Benutzers. Der Wert ManipulationDelta.Scale stellt die Änderung der Skalierung der Pinch-Geste dar, so dass eine kleine Vergrößerung der Pinch-Geste eine Zahl ist, die etwas größer als 1,0 ist, und eine kleine Verkleinerung der Pinch-Geste eine Zahl, die etwas kleiner als 1,0 ist. In diesem Beispiel wird der aktuelle Wert der Zoomsteuerung mit dem Skalendelta multipliziert.
Bevor Sie den Zoomfaktor einstellen, müssen Sie sicherstellen, dass der Wert nicht unter dem vom Gerät unterstützten Mindestwert liegt, wie er in der Eigenschaft ZoomControl.Min angegeben ist. Stellen Sie außerdem sicher, dass der Wert kleiner oder gleich dem Wert ZoomControl.Max ist. Schließlich müssen Sie sicherstellen, dass der Zoomfaktor ein Vielfaches der vom Gerät unterstützten Zoomschrittgröße ist, wie durch die Eigenschaft Step angegeben. Wenn Ihr Zoomfaktor diese Anforderungen nicht erfüllt, wird eine Ausnahme ausgelöst, wenn Sie versuchen, die Zoomstufe auf dem Aufnahmegerät einzustellen.
Legen Sie die Zoomstufe auf dem Aufnahmegerät fest, indem Sie ein neues Objekt ZoomSettings erstellen. Setzen Sie die Eigenschaft Mode auf ZoomTransitionMode.Smooth und setzen Sie dann die Eigenschaft Value auf den gewünschten Zoomfaktor. Rufen Sie schließlich ZoomControl.Configure auf, um den neuen Zoomwert auf dem Gerät einzustellen. Das Gerät geht nahtlos auf den neuen Zoomwert über.
private void PreviewControl_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
var zoomControl = _mediaCapture.VideoDeviceController.ZoomControl;
// Example zoom factor calculation based on size of scale gesture
var zoomFactor = zoomControl.Value * e.Delta.Scale;
if (zoomFactor < zoomControl.Min) zoomFactor = zoomControl.Min;
if (zoomFactor > zoomControl.Max) zoomFactor = zoomControl.Max;
zoomFactor = zoomFactor - (zoomFactor % zoomControl.Step);
var settings = new ZoomSettings();
settings.Mode = ZoomTransitionMode.Smooth;
settings.Value = zoomFactor;
_mediaCapture.VideoDeviceController.ZoomControl.Configure(settings);
}