Manuelle Kamerasteuerungen für Foto- und Videoaufnahmen

In diesem Artikel erfahren Sie, wie Sie manuelle Gerätesteuerelemente verwenden, um erweiterte Foto- und Videoaufnahmeszenarien zu ermöglichen, einschließlich optischer Bildstabilisierung und flüssiger Zoom.

Die in diesem Artikel beschriebenen Steuerelemente werden ihrer App mit demselben Muster hinzugefügt. Überprüfen Sie zunächst, ob das Steuerelement auf dem aktuellen Gerät unterstützt wird, auf dem Ihre App ausgeführt wird. Wenn das Steuerelement unterstützt wird, legen Sie den gewünschten Modus für das Steuerelement fest. Wenn ein bestimmtes Steuerelement auf dem aktuellen Gerät nicht unterstützt wird, sollten Sie das UI-Element deaktivieren oder ausblenden, mit dem der Benutzer das Feature aktivieren kann.

Note

Dieser Artikel baut auf Konzepten und Code auf, die in der einfachen Foto-, Video- und Audioaufnahme mit MediaCapture erläutert werden. In diesem Artikel werden die Schritte für die Implementierung grundlegender Foto- und Videoaufnahmen beschrieben. Es wird empfohlen, sich mit dem grundlegenden Medienaufnahmemuster in diesem Artikel vertraut zu machen, bevor Sie zu erweiterten Aufnahmeszenarien wechseln. Der Code in diesem Artikel geht davon aus, dass Ihre App bereits über eine Instanz von MediaCapture verfügt, die ordnungsgemäß initialisiert wurde.

Exposition

Mit dem ExposureControl können Sie die Verschlussgeschwindigkeit festlegen, die während der Foto- oder Videoaufnahme verwendet wird.

In diesem Beispiel wird ein Schieberegler verwendet, um den aktuellen Belichtungswert anzupassen, sowie ein Kontrollkästchen, um die automatische Belichtungsanpassung ein- oder auszuschalten.

<Slider Name="slExposure" ValueChanged="slExposure_ValueChanged"/>
<TextBlock Name="tbExposure" Text="{Binding ElementName=slExposure,Path=Value}"/>
<CheckBox Name="cbExposureAuto" Content="Auto" Checked="cbExposure_CheckedChanged" Unchecked="cbExposure_CheckedChanged"/>

Überprüfen Sie, ob das aktuelle Aufnahmegerät das ExposureControl unterstützt, indem Sie die unterstützte Eigenschaft überprüfen. Wenn das Steuerelement unterstützt wird, können Sie die Benutzeroberfläche für dieses Feature anzeigen und aktivieren. Legen Sie den aktivierten Zustand des Kontrollkästchens fest, um anzugeben, ob die automatische Belichtungsanpassung derzeit für den Wert der Auto-Eigenschaft aktiv ist.

Der Belichtungswert muss sich innerhalb des vom Gerät unterstützten Bereichs befinden und muss ein Inkrement der unterstützten Schrittgröße 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 Schiebereglersteuerelements verwendet werden.

Legen Sie den Wert des Schieberegler-Steuerelements auf den aktuellen Wert des ExposureControl-Steuerelements fest, nachdem Sie die Registrierung des ValueChanged-Ereignishandlers aufgehoben haben , sodass das Ereignis nicht ausgelöst wird, wenn der Wert festgelegt wird.

var exposureControl = m_mediaCapture.VideoDeviceController.ExposureControl;

if (exposureControl.Supported)
{
    cbExposureAuto.Visibility = Visibility.Visible;
    slExposure.Visibility = Visibility.Visible;

    cbExposureAuto.IsChecked = exposureControl.Auto;

    slExposure.Minimum = exposureControl.Min.Ticks;
    slExposure.Maximum = exposureControl.Max.Ticks;
    slExposure.StepFrequency = exposureControl.Step.Ticks;

    slExposure.ValueChanged -= slExposure_ValueChanged;
    var value = exposureControl.Value;
    slExposure.Value = value.Ticks;
    slExposure.ValueChanged += slExposure_ValueChanged;
}
else
{
    cbExposureAuto.Visibility = Visibility.Collapsed;
    slExposure.Visibility = Visibility.Collapsed;
}

Rufen Sie im ValueChanged-Ereignishandler den aktuellen Wert des Steuerelements ab, und legen Sie den Belichtungswert fest, indem Sie SetValueAsync aufrufen.

private async void slExposure_ValueChanged(object sender, Microsoft.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
{
    var value = TimeSpan.FromTicks((long)(sender as Slider).Value);
    await m_mediaCapture.VideoDeviceController.ExposureControl.SetValueAsync(value);
}

Aktivieren oder deaktivieren Sie im CheckedChanged-Ereignishandler des Kontrollkästchens für die automatische Belichtung die automatische Belichtungsanpassung, indem Sie SetAutoAsync aufrufen und einen booleschen Wert übergeben.

private async void cbExposure_CheckedChanged(object sender, RoutedEventArgs e)
{
    if (!m_isPreviewing)
    {
        // Auto exposure only supported while preview stream is running.
        return;
    }

    var autoExposure = ((sender as CheckBox).IsChecked == true);
    await m_mediaCapture.VideoDeviceController.ExposureControl.SetAutoAsync(autoExposure);
}

Important

Der automatische Belichtungsmodus ist nur verfügbar, während der Vorschaustream läuft. Stellen Sie sicher, dass der Vorschaustream läuft, bevor Sie die automatische Belichtung aktivieren.

Belichtungskorrektur

Mit dem ExposureCompensationControl können Sie die während der Foto- oder Videoaufnahme verwendete Belichtungskorrektur festlegen.

In diesem Beispiel wird ein Slider-Steuerelement verwendet, um den aktuellen Belichtungskorrekturwert anzupassen.

<Slider Name="slEV" ValueChanged="slEV_ValueChanged"/>
<TextBlock Text="{Binding ElementName=slEV,Path=Value}" Name="tbEV"/>

Überprüfen Sie, ob das aktuelle Aufnahmegerät das ExposureCompensationControl unterstützt, indem Sie die unterstützte Eigenschaft überprüfen. Wenn das Steuerelement unterstützt wird, können Sie die Benutzeroberfläche für dieses Feature anzeigen und aktivieren.

Der Belichtungskorrekturwert muss sich innerhalb des vom Gerät unterstützten Bereichs befinden und ein Inkrement der unterstützten Schrittgröße 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 Schiebereglersteuerelements verwendet werden.

Legen Sie den Wert des Schieberegler-Steuerelements auf den aktuellen Wert des ExposureCompensationControl-Steuerelements fest, nachdem Sie die Registrierung des ValueChanged-Ereignishandlers aufgehoben haben , sodass das Ereignis beim Festlegen des Werts nicht ausgelöst wird.

var exposureCompensationControl = m_mediaCapture.VideoDeviceController.ExposureCompensationControl;

if (exposureCompensationControl.Supported)
{
    slEV.Visibility = Visibility.Visible;
    slEV.Minimum = exposureCompensationControl.Min;
    slEV.Maximum = exposureCompensationControl.Max;
    slEV.StepFrequency = exposureCompensationControl.Step;

    slEV.ValueChanged -= slEV_ValueChanged;
    slEV.Value = exposureCompensationControl.Value;
    slEV.ValueChanged += slEV_ValueChanged;
}
else
{
    slEV.Visibility = Visibility.Collapsed;
}

Rufen Sie im ValueChanged-Ereignishandler den aktuellen Wert des Steuerelements ab, und legen Sie den Belichtungswert fest, indem Sie SetValueAsync aufrufen.

private async void slEV_ValueChanged(object sender, Microsoft.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
{
    var value = (sender as Slider).Value;
    await m_mediaCapture.VideoDeviceController.ExposureCompensationControl.SetValueAsync((float)value);
}

Blitzlicht

Mit dem FlashControl können Sie den Blitz aktivieren oder deaktivieren oder den automatischen Blitz aktivieren, wobei das System dynamisch bestimmt, ob der Blitz verwendet werden soll. Mit diesem Bedienelement können Sie auch die automatische Rote-Augen-Reduzierung auf Geräten aktivieren, die sie unterstützen. Diese Einstellungen gelten alle für das Aufnehmen von Fotos. Das TorchControl ist ein separates Steuerelement zum Aktivieren oder Deaktivieren der Taschenlampe für die Videoaufnahme.

In diesem Beispiel wird eine Reihe von Optionsfeldern verwendet, mit denen der Benutzer zwischen den Einstellungen "Ein-", "Aus" und "Automatischer Blitz" wechseln kann. Ein Kontrollkästchen ist ebenfalls vorhanden, mit dem die Rote-Augen-Reduzierung und die Videoleuchte ein- oder ausgeschaltet werden können.

<RadioButton Name="rbFlashOn" Content="On" Checked="rbFlashOn_Checked"/>
<RadioButton Name="rbFlashAuto" Content="Auto" Checked="rbFlashAuto_Checked"/>
<RadioButton Name="rbFlashOff" Content="Off" Checked="rbFlashOff_Checked"/>
<CheckBox Name="cbRedEyeFlash" Content="Red Eye" Visibility="Collapsed" Checked="cbRedEyeFlash_CheckedChanged" Unchecked="cbRedEyeFlash_CheckedChanged"/>
<CheckBox Name="cbTorch" Content="Video Light" Visibility="Collapsed" Checked="cbTorch_CheckedChanged" Unchecked="cbTorch_CheckedChanged"/>

Überprüfen Sie, ob das aktuelle Aufnahmegerät flashControl unterstützt, indem Sie die unterstützte Eigenschaft überprüfen. Wenn das Steuerelement unterstützt wird, können Sie die Benutzeroberfläche für dieses Feature anzeigen und aktivieren. Wenn FlashControl unterstützt wird, wird die automatische Rote-Augen-Reduktion möglicherweise unterstützt, möglicherweise aber auch nicht. Überprüfen Sie daher die RedEyeReductionSupported-Eigenschaft, bevor Sie die Benutzeroberfläche aktivieren. Da das TorchControl von der Blitzsteuerung getrennt ist, müssen Sie vor der Verwendung auch dessen Eigenschaft Supported überprüfen.

Aktivieren oder deaktivieren Sie im Ereignishandler Checked für jede der Optionsschaltflächen für den Blitz die jeweilige Flash-Einstellung. Beachten Sie, dass Sie, um festzulegen, dass der Blitz immer verwendet wird, die Eigenschaft Enabled auf true und die Eigenschaft Auto auf false festlegen müssen.

var flashControl = m_mediaCapture.VideoDeviceController.FlashControl;

if (flashControl.Supported)
{
    rbFlashAuto.Visibility = Visibility.Visible;
    rbFlashOn.Visibility = Visibility.Visible;
    rbFlashOff.Visibility = Visibility.Visible;

    rbFlashAuto.IsChecked = true;

    if (flashControl.RedEyeReductionSupported)
    {
        cbRedEyeFlash.Visibility = Visibility.Visible;
    }

    // Video light is not strictly part of flash, but users might expect to find it there
    if (m_mediaCapture.VideoDeviceController.TorchControl.Supported)
    {
        cbTorch.Visibility = Visibility.Visible;
    }
}
else
{
    rbFlashAuto.Visibility = Visibility.Collapsed;
    rbFlashOn.Visibility = Visibility.Collapsed;
    rbFlashOff.Visibility = Visibility.Collapsed;
}

private void rbFlashOn_Checked(object sender, RoutedEventArgs e)
{
    m_mediaCapture.VideoDeviceController.FlashControl.Enabled = true;
    m_mediaCapture.VideoDeviceController.FlashControl.Auto = false;
}

private void rbFlashAuto_Checked(object sender, RoutedEventArgs e)
{
    m_mediaCapture.VideoDeviceController.FlashControl.Enabled = true;
    m_mediaCapture.VideoDeviceController.FlashControl.Auto = true;
}

private void rbFlashOff_Checked(object sender, RoutedEventArgs e)
{
    m_mediaCapture.VideoDeviceController.FlashControl.Enabled = false;
}

Legen Sie im Handler für das Red Eye Reduction-Kontrollkästchen die RedEyeReduction-Eigenschaft auf den entsprechenden Wert fest.


//private void cbRedEyeFlash_CheckedChanged(object sender, RoutedEventArgs e)
private void cbRedEyeFlash_CheckedChanged(object sender, RoutedEventArgs e)
{
    m_mediaCapture.VideoDeviceController.FlashControl.RedEyeReduction = (cbRedEyeFlash.IsChecked == true);
}

Legen Sie abschließend im Handler für das Kontrollkästchen "Videolampe" die Eigenschaft "Enabled " auf den entsprechenden Wert fest.

private void cbTorch_CheckedChanged(object sender, RoutedEventArgs e)
{
    m_mediaCapture.VideoDeviceController.TorchControl.Enabled = (cbTorch.IsChecked == true);

    if(! (m_isPreviewing && m_isRecording))
    {
        System.Diagnostics.Debug.WriteLine("Torch may not emit light if preview and video capture are not running.");
    }
}

Note

Auf einigen Geräten gibt die Taschenlampe kein Licht aus, auch wenn TorchControl.Enabled auf "true" festgelegt ist, es sei denn, das Gerät hat einen Vorschaudatenstrom ausgeführt und zeichnet videos aktiv auf. Die empfohlene Reihenfolge der Schritte ist, zunächst die Videovorschau zu aktivieren, dann den Blitz zu aktivieren, indem Sie Enabled auf true setzen, und anschließend die Videoaufnahme zu starten. Auf einigen Geräten schaltet sich der Blitz nach dem Start der Vorschau ein. Auf anderen Geräten leuchtet die Taschenlampe möglicherweise erst, wenn die Videoaufnahme gestartet wird.

Fokus

Drei verschiedene häufig verwendete Methoden zum Anpassen des Kamerafokus werden vom FocusControlObjekt, kontinuierlichem Autofokus, Tippen zum Fokus und manueller Fokus unterstützt. Eine Kamera-App unterstützt möglicherweise alle drei Methoden, aber zur Lesbarkeit erläutert dieser Artikel jede Technik separat. In diesem Abschnitt wird auch erläutert, wie das Fokushilfelicht aktiviert wird.

Fortlaufender Autofokus

Durch aktivieren des fortlaufenden Autofokus wird die Kamera angewiesen, den Fokus dynamisch anzupassen, um zu versuchen, den Betreff des Fotos oder Videos im Fokus zu halten. In diesem Beispiel wird ein Optionsfeld verwendet, um den kontinuierlichen Autofokus ein- und auszuschalten.

<RadioButton Content="CAF" Name="rbContinuousAutoFocus" Checked="rbContinuousAutoFocus_Checked"/>

Überprüfen Sie, ob das aktuelle Aufnahmegerät das FocusControl unterstützt, indem Sie die unterstützte Eigenschaft überprüfen. Ermitteln Sie als Nächstes, ob der fortlaufende Autofokus unterstützt wird, indem Sie die Liste SupportedFocusModes überprüfen, ob sie den Wert FocusMode.Continuous enthält, und zeigen Sie ggf. das Optionsfeld für den fortlaufenden Autofokus an.

var focusControl = m_mediaCapture.VideoDeviceController.FocusControl;

if (focusControl.Supported)
{
    rbContinuousAutoFocus.Visibility = focusControl.SupportedFocusModes.Contains(FocusMode.Continuous)
        ? Visibility.Visible : Visibility.Collapsed;
}
else
{
    rbContinuousAutoFocus.Visibility = Visibility.Collapsed;
}

Verwenden Sie im Ereignishandler Checked für das Optionsfeld für den kontinuierlichen Autofokus die Eigenschaft VideoDeviceController.FocusControl, um eine Instanz des Steuerelements zu erhalten. Rufen Sie UnlockAsync auf, um das Steuerelement zu entsperren, falls Ihre App zuvor LockAsync aufgerufen hat, um einen der anderen Fokusmodi zu aktivieren.

Erstellen Sie ein neues FocusSettingsObjekt, und legen Sie das Mode-Eigenschaft auf Continuous fest. Legen Sie die AutoFocusRange-Eigenschaft auf einen Wert fest, der für Ihr App-Szenario geeignet ist oder vom Benutzer auf der Benutzeroberfläche ausgewählt wurde. Übergeben Sie das FocusSettings-Objekt an die Configure-Methode , und rufen Sie dann FocusAsync auf, um den fortlaufenden Autofokus zu initiieren.

private async void rbContinuousAutoFocus_Checked(object sender, RoutedEventArgs e)
{
    if(! m_isPreviewing)
    {
        // Autofocus only supported while preview stream is running.
        return;
    }

    var focusControl = m_mediaCapture.VideoDeviceController.FocusControl;
    await focusControl.UnlockAsync();
    var settings = new FocusSettings { Mode = FocusMode.Continuous, AutoFocusRange = AutoFocusRange.FullRange };
    focusControl.Configure(settings);
    await focusControl.FocusAsync();
}

Important

Der Autofokusmodus wird nur unterstützt, solange der Vorschau-Stream läuft. Stellen Sie sicher, dass der Vorschaustream läuft, bevor Sie den kontinuierlichen Autofokus aktivieren.

Tippen, um den Fokus zu setzen

Die Tap-to-Focus-Technik verwendet die FocusControl und die RegionsOfInterestControl um einen Unterbereich des Aufnahmeframes anzugeben, in dem sich das Aufnahmegerät konzentrieren soll. Der Fokusbereich wird bestimmt, indem der Benutzer auf den Bildschirm tippt, auf dem der Vorschaudatenstrom angezeigt wird.

In diesem Beispiel wird eine Optionsschaltfläche verwendet, um den Tippen-zum-Fokussieren-Modus zu aktivieren und zu deaktivieren.

<RadioButton Content="rbTapToFocus" Name="TapFocusRadioButton" Checked="rbTapToFocus_Checked"/>

Überprüfen Sie, ob das aktuelle Aufnahmegerät das FocusControl unterstützt, indem Sie die unterstützte Eigenschaft überprüfen. RegionsOfInterestControl muss unterstützt werden und muss mindestens eine Region unterstützen, um diese Technik verwenden zu können. Überprüfen Sie die Eigenschaften AutoFocusSupported und MaxRegions, um zu bestimmen, ob die Optionsschaltfläche für „Tippen zum Fokussieren“ angezeigt oder ausgeblendet werden soll.

var focusControl = m_mediaCapture.VideoDeviceController.FocusControl;

if (focusControl.Supported)
{
    TapFocusRadioButton.Visibility = (m_mediaCapture.VideoDeviceController.RegionsOfInterestControl.AutoFocusSupported &&
                                      m_mediaCapture.VideoDeviceController.RegionsOfInterestControl.MaxRegions > 0)
                                      ? Visibility.Visible : Visibility.Collapsed;
}
else
{
    TapFocusRadioButton.Visibility = Visibility.Collapsed;
}

Verwenden Sie im "Checked "-Ereignishandler für das Optionsfeld "Tippen zum Fokus" 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 rbTapToFocus_Checked(object sender, RoutedEventArgs e)
{
    // Lock focus in case Continuous Autofocus was active when switching to Tap-to-focus
    var focusControl = m_mediaCapture.VideoDeviceController.FocusControl;
    await focusControl.LockAsync();
    // Wait for user tap
}

Dieses Beispiel konzentriert sich auf einen Bereich, wenn der Benutzer auf den Bildschirm tippt, und entfernt dann den Fokus aus diesem Bereich, wenn der Benutzer erneut tippt, z. B. eine Umschaltfläche. Verwenden Sie eine boolesche Variable, um den aktuellen Umschaltzustand zu verfolgen.

bool _isFocused = false;

Der nächste Schritt besteht darin, das Ereignis zu überwachen, wenn der Benutzer auf den Bildschirm tippt, indem das TappedEreignis des CaptureElement behandelt wird, das derzeit den Vorschaudatenstrom der Aufnahme anzeigt. Wenn die Kamera derzeit keine Vorschau anzeigt oder der Modus "Tippen zum Fokus" deaktiviert ist, kehren Sie vom Handler zurück, ohne etwas zu tun.

Wenn die Trackingvariable _isFocused auf false gesetzt wird und die Kamera derzeit nicht gerade fokussiert (ermittelt anhand der Eigenschaft FocusState von FocusControl), beginnen Sie den Tap-to-Focus-Vorgang. Ruft die Position des Tippens des Benutzers aus den Ereignisargumenten ab, die an den Handler übergeben werden. Dieses Beispiel nutzt auch diese Gelegenheit, um die Größe der Region auszuwählen, auf die fokussiert wird. In diesem Fall beträgt die Größe 1/4 der kleinsten Dimension des Aufnahmeelements. Übergeben Sie die Tippposition und die Bereichsgröße an die TapToFocus-Hilfsmethode , die im nächsten Abschnitt definiert ist.

Wenn der Schalter _isFocused auf true gesetzt ist, sollte ein Tippen des Benutzers den Fokus vom vorherigen Bereich entfernen. Dies erfolgt in der unten gezeigten TapUnfocus-Hilfsmethode .

private async void mpePreview_Tapped(object sender, TappedRoutedEventArgs e)
{
    if (!m_isPreviewing || (TapFocusRadioButton.IsChecked != true)) return;

    if (!_isFocused && m_mediaCapture.VideoDeviceController.FocusControl.FocusState != MediaCaptureFocusState.Searching)
    {
        var smallEdge = Math.Min(mpePreview.ActualWidth, mpePreview.ActualHeight);

        // Make the focus rectangle 1/4th the length of the preview control's shortest edge.
        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();
    }
}

Legen Sie in der TapToFocus-Hilfsmethode zuerst den Schalter _isFocused auf „true“ fest, sodass das nächste Tippen auf den Bildschirm den Fokus vom angetippten Bereich löst.

Die nächste Aufgabe in dieser Hilfsmethode besteht darin, das Rechteck innerhalb des Vorschaudatenstroms zu bestimmen, das dem Fokussteuerelement zugewiesen wird. Dies erfordert zwei Schritte. Der erste Schritt besteht darin, das Rechteck zu bestimmen, das der Vorschaudatenstrom innerhalb des Steuerelements CaptureElement verwendet. Dies hängt von den Abmessungen des Vorschaudatenstroms und der Ausrichtung des Geräts ab. Die Hilfsmethode GetPreviewStreamRectInControl, die am Ende dieses Abschnitts angezeigt wird, führt diese Aufgabe aus und gibt das Rechteck zurück, das den Vorschaudatenstrom enthält.

Die nächste Aufgabe in TapToFocus besteht darin, die Position des Tippens und die gewünschte Fokusrechteckgröße zu konvertieren, die im CaptureElement.Tapped-Ereignishandler bestimmt wurden, in Koordinaten innerhalb des Aufnahmedatenstroms. Die ConvertUiTapToPreviewRect-Hilfsmethode , die weiter unten in diesem Abschnitt gezeigt wird, führt diese Konvertierung aus und gibt das Rechteck in Aufnahmedatenstromkoordinaten zurück, in denen der Fokus angefordert wird.

Nachdem das Zielrechteck abgerufen wurde, erstellen Sie ein neues RegionOfInterest-Objekt, und legen Sie das Bounds-Eigenschaft auf das Zielrechteck fest, das in den vorherigen Schritten abgerufen wurde.

Rufen Sie die FocusControl des Erfassungsgeräts ab. Erstellen Sie ein neues FocusSettingsobjekt, und legen Sie das Mode und AutoFocusRange an die gewünschten Werte, nachdem Sie überprüft haben, ob sie vom FocusControl unterstützt werden. Rufen Sie Configure für das FocusControl auf, um Ihre Einstellungen zu aktivieren und dem Gerät zu signalisieren, dass es beginnt, auf den angegebenen Bereich zu fokussieren.

Rufen Sie als Nächstes das RegionsOfInterestControl des Erfassungsgeräts ab, und rufen Sie SetRegionsAsync auf, um die aktive Region festzulegen. Mehrere interessante Regionen können auf Geräten festgelegt werden, die sie unterstützen, in diesem Beispiel wird jedoch nur eine einzelne Region festgelegt.

Rufen Sie schließlich FocusAsync für focusControl auf, um den Fokus zu initiieren.

Important

Bei der Implementierung von Tap-to-Focus ist die Reihenfolge der Abläufe wichtig. Sie sollten diese APIs in der folgenden Reihenfolge aufrufen:

  1. FocusControl.Configure
  2. RegionsOfInterestControl.SetRegionsAsync
  3. FocusControl.FocusAsync
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 = m_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 = m_mediaCapture.VideoDeviceController.RegionsOfInterestControl;
    await roiControl.SetRegionsAsync(new[] { regionOfInterest }, true);

    await focusControl.FocusAsync();
}

Rufen Sie in der TapUnfocus-Hilfsmethode die RegionsOfInterestControl-Methode ab, und rufen Sie ClearRegionsAsync auf, um den Bereich zu löschen, der mit dem Steuerelement in der TapToFocus-Hilfsmethode registriert wurde. Rufen Sie dann FocusControl ab, und rufen Sie FocusAsync auf, damit das Gerät ohne einen Interessenbereich erneut fokussiert wird.

private async Task TapUnfocus()
{
    _isFocused = false;

    var roiControl = m_mediaCapture.VideoDeviceController.RegionsOfInterestControl;
    await roiControl.ClearRegionsAsync();

    var focusControl = m_mediaCapture.VideoDeviceController.FocusControl;
    await focusControl.FocusAsync();
}

Die GetPreviewStreamRectInControl-Hilfsmethode 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, wobei alle durch Letterboxing entstandenen Auffüllränder abgeschnitten werden, die das Steuerelement möglicherweise hinzufügt, um das Seitenverhältnis des Streams beizubehalten. Diese Methode verwendet Klassenmitgliedsvariablen, die im grundlegenden Beispielcode zur Medienerfassung definiert sind, der in Einfache Foto-, Video- und Audioaufnahme mit MediaCapture zu finden ist.

public Rect GetPreviewStreamRectInControl()
{
    var result = new Rect();

    var previewResolution = m_mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties;

    // In case this function is called before everything is initialized correctly, return an empty result
    if (mpePreview == null || mpePreview.ActualHeight < 1 || mpePreview.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 (m_displayOrientation == DisplayOrientations.Portrait || m_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 = mpePreview.ActualWidth;
    result.Height = mpePreview.ActualHeight;

    // If UI is "wider" than preview, letterboxing will be on the sides
    if ((mpePreview.ActualWidth / mpePreview.ActualHeight > streamWidth / (double)streamHeight))
    {
        var scale = mpePreview.ActualHeight / streamHeight;
        var scaledWidth = streamWidth * scale;

        result.X = (mpePreview.ActualWidth - scaledWidth) / 2.0;
        result.Width = scaledWidth;
    }
    else // Preview stream is "wider" than UI, so letterboxing will be on the top+bottom
    {
        var scale = mpePreview.ActualWidth / streamWidth;
        var scaledHeight = streamHeight * scale;

        result.Y = (mpePreview.ActualHeight - scaledHeight) / 2.0;
        result.Height = scaledHeight;
    }

    return result;
}

Die ConvertUiTapToPreviewRect-Hilfsmethode verwendet als Argumente die Position des Tippereignisses, die gewünschte Größe des Fokusbereichs und das Rechteck mit dem Vorschaudatenstrom, der aus der GetPreviewStreamRectInControl-Hilfsmethode abgerufen wurde. Diese Methode verwendet diese Werte und die aktuelle Ausrichtung des Geräts, um das Rechteck innerhalb des Vorschaudatenstroms zu berechnen, der den gewünschten Bereich enthält. Auch diese Methode verwendet Klassenmembervariablen, die im grundlegenden Beispielcode zur Medienerfassung definiert sind, der in Aufnehmen von Fotos und Videos mit MediaCapture zu finden ist.

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 (m_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 (m_displayOrientation == DisplayOrientations.Portrait || m_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

Die manuelle Fokustechnik verwendet ein Schieberegler-Steuerelement , um die aktuelle Fokustiefe des Aufnahmegeräts festzulegen. Ein Optionsfeld dient dazu, den manuellen Fokus ein- und auszuschalten.

<Slider Name="slFocus" IsEnabled="{Binding ElementName=rbManualFocus,Path=IsChecked}" ValueChanged="slFocus_ValueChanged"/>
<TextBlock Text="{Binding ElementName=slFocus,Path=Value,FallbackValue='0'}"/>
<RadioButton Content="Manual" Name="rbManualFocus" Checked="rbManualFocus_Checked" IsChecked="False"/>

Überprüfen Sie, ob das aktuelle Aufnahmegerät das FocusControl unterstützt, indem Sie die unterstützte Eigenschaft überprüfen. Wenn das Steuerelement unterstützt wird, können Sie die Benutzeroberfläche für dieses Feature anzeigen und aktivieren.

Der Fokuswert muss sich innerhalb des vom Gerät unterstützten Bereichs befinden und muss ein Inkrement der unterstützten Schrittgröße 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 Schiebereglersteuerelements verwendet werden.

Legen Sie den Wert des Schiebereglersteuerelements auf den aktuellen Wert von FocusControl fest, nachdem Sie die Registrierung des ValueChanged-Ereignishandlers aufgehoben haben , sodass das Ereignis beim Festlegen des Werts nicht ausgelöst wird.

var focusControl = m_mediaCapture.VideoDeviceController.FocusControl;

if (focusControl.Supported)
{
    slFocus.Visibility = Visibility.Visible;
    rbManualFocus.Visibility = Visibility.Visible;

    slFocus.Minimum = focusControl.Min;
    slFocus.Maximum = focusControl.Max;
    slFocus.StepFrequency = focusControl.Step;


    slFocus.ValueChanged -= slFocus_ValueChanged;
    slFocus.Value = focusControl.Value;
    slFocus.ValueChanged += slFocus_ValueChanged;
}
else
{
    slFocus.Visibility = Visibility.Collapsed;
    rbManualFocus.Visibility = Visibility.Collapsed;
}

Rufen Sie im Ereignishandler Aktiviert für das Optionsfeld für manuellen Fokus das Objekt FocusControl ab und rufen Sie LockAsync auf, falls Ihre App den Fokus zuvor mit einem Aufruf von UnlockAsync entsperrt hatte.

private async void rbManualFocus_Checked(object sender, RoutedEventArgs e)
{
    var focusControl = m_mediaCapture.VideoDeviceController.FocusControl;
    await focusControl.LockAsync();
}

Rufen Sie im ValueChanged-Ereignishandler des manuellen Fokusschiebereglers den aktuellen Wert des Steuerelements ab, und legen Sie den Fokuswert fest, indem Sie SetValueAsync aufrufen.

private async void slFocus_ValueChanged(object sender, Microsoft.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
{
    var value = (sender as Slider).Value;
    await m_mediaCapture.VideoDeviceController.FocusControl.SetValueAsync((uint)value);
}

Aktivieren des Fokuslichts

Auf Geräten, die dies unterstützen, können Sie ein Fokushilfelicht aktivieren, um den Gerätefokus zu unterstützen. In diesem Beispiel wird ein Kontrollkästchen verwendet, um das Fokushilfelicht zu aktivieren oder zu deaktivieren.

<CheckBox Content="Assist Light" Name="cbFocusLight" IsEnabled="{Binding ElementName=rbTapToFocus,Path=IsChecked}"
Checked="cbFocusLight_CheckedChanged" Unchecked="cbFocusLight_CheckedChanged"/>

Überprüfen Sie, ob das aktuelle Aufnahmegerät flashControl unterstützt, indem Sie die unterstützte Eigenschaft überprüfen. Prüfen Sie auch AssistantLightSupported, um sicherzustellen, dass auch das Assistenzlicht unterstützt wird. Wenn beides unterstützt wird, können Sie die Benutzeroberfläche für dieses Feature anzeigen und aktivieren.

var focusControl = m_mediaCapture.VideoDeviceController.FocusControl;

if (focusControl.Supported)
{

    cbFocusLight.Visibility = (m_mediaCapture.VideoDeviceController.FlashControl.Supported &&
                                     m_mediaCapture.VideoDeviceController.FlashControl.AssistantLightSupported) ? Visibility.Visible : Visibility.Collapsed;
}
else
{
    cbFocusLight.Visibility = Visibility.Collapsed;
}

Rufen Sie im Ereignishandler CheckedChanged das FlashControl-Objekt des Aufnahmegeräts ab. Legen Sie die AssistantLightEnabled-Eigenschaft fest, um das Fokuslicht zu aktivieren oder zu deaktivieren.

private void cbFocusLight_CheckedChanged(object sender, RoutedEventArgs e)
{
    var flashControl = m_mediaCapture.VideoDeviceController.FlashControl;

    flashControl.AssistantLightEnabled = (cbFocusLight.IsChecked == true);
}

ISO-Geschwindigkeit

Mit dem IsoSpeedControl können Sie die während der Foto- oder Videoaufnahme verwendete ISO-Geschwindigkeit festlegen.

In diesem Beispiel wird ein Slider-Steuerelement verwendet, um den aktuellen Belichtungskorrekturwert anzupassen, sowie ein Kontrollkästchen, um die automatische Anpassung der ISO-Empfindlichkeit ein- oder auszuschalten.

<Slider Name="slIso" ValueChanged="slIso_ValueChanged"/>
<TextBlock Text="{Binding ElementName=slIso,Path=Value}" Visibility="{Binding ElementName=slIso,Path=Visibility}"/>
<CheckBox Name="cbIsoAuto" Content="Auto" Checked="cbIsoAuto_CheckedChanged" Unchecked="cbIsoAuto_CheckedChanged"/>

Überprüfen Sie, ob das aktuelle Aufnahmegerät isoSpeedControl unterstützt, indem Sie die unterstützte Eigenschaft überprüfen. Wenn das Steuerelement unterstützt wird, können Sie die Benutzeroberfläche für dieses Feature anzeigen und aktivieren. Legen Sie den aktivierten Status des Kontrollkästchens fest, um anzugeben, ob die automatische Anpassung der ISO-Geschwindigkeit derzeit auf den Wert der Auto-Eigenschaft aktiv ist.

Der ISO-Geschwindigkeitswert muss sich innerhalb des vom Gerät unterstützten Bereichs befinden und eine Inkrementierung der unterstützten Schrittgröße 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 Schiebereglersteuerelements verwendet werden.

Legen Sie den Wert des Schiebereglersteuerelements auf den aktuellen Wert von IsoSpeedControl fest, nachdem Sie die Registrierung des ValueChanged-Ereignishandlers aufgehoben haben , sodass das Ereignis beim Festlegen des Werts nicht ausgelöst wird.

private void bUpdateIsoControlCapabilities_Click(object sender, RoutedEventArgs e)
{
    var isoSpeedControl = m_mediaCapture.VideoDeviceController.IsoSpeedControl;

    if (isoSpeedControl.Supported)
    {
        cbIsoAuto.Visibility = Visibility.Visible;
        slIso.Visibility = Visibility.Visible;

        cbIsoAuto.IsChecked = isoSpeedControl.Auto;

        slIso.Minimum = isoSpeedControl.Min;
        slIso.Maximum = isoSpeedControl.Max;
        slIso.StepFrequency = isoSpeedControl.Step;

        slIso.ValueChanged -= slIso_ValueChanged;
        slIso.Value = isoSpeedControl.Value;
        slIso.ValueChanged += slIso_ValueChanged;
    }
    else
    {
        cbIsoAuto.Visibility = Visibility.Collapsed;
        slIso.Visibility = Visibility.Collapsed;
    }
}

Rufen Sie im ValueChanged-Ereignishandler den aktuellen Wert des Steuerelements ab, und legen Sie den ISO-Geschwindigkeitswert fest, indem Sie SetValueAsync aufrufen.

private async void slIso_ValueChanged(object sender, Microsoft.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
{
    var value = (sender as Slider).Value;
    await m_mediaCapture.VideoDeviceController.IsoSpeedControl.SetValueAsync((uint)value);
}

Aktivieren Sie im CheckedChanged-Ereignishandler des Kontrollkästchens für die automatische ISO-Empfindlichkeit die automatische Anpassung der ISO-Empfindlichkeit, indem Sie SetAutoAsync aufrufen. Deaktivieren Sie die automatische ANPASSUNG der ISO-Geschwindigkeit, indem Sie SetValueAsync aufrufen und den aktuellen Wert des Schieberegler-Steuerelements übergeben.

private async void cbIsoAuto_CheckedChanged(object sender, RoutedEventArgs e)
{
    var autoIso = (sender as CheckBox).IsChecked == true;

    if (autoIso)
    {
        await m_mediaCapture.VideoDeviceController.IsoSpeedControl.SetAutoAsync();
    }
    else
    {
        await m_mediaCapture.VideoDeviceController.IsoSpeedControl.SetValueAsync((uint)slIso.Value);
    }
}

Optische Bildstabilisierung

Die optische Bildstabilisierung (OIS) stabilisiert einen aufgenommenen Videodatenstrom, indem das Hardwareaufnahmegerät mechanisch manipuliert wird, was ein überlegenes Ergebnis als die digitale Stabilisierung bieten 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 Effects for video capture.

Ermitteln Sie, ob OIS auf dem aktuellen Gerät unterstützt wird, indem Sie die OpticalImageStabilizationControl.Supported-Eigenschaft überprüfen.

Das OIS-Steuerelement unterstützt drei Modi: ein, aus und automatisch, was bedeutet, dass das Gerät dynamisch bestimmt, ob OIS die Medienaufnahme verbessern würde und wenn ja, OIS aktiviert. Um festzustellen, ob ein bestimmter Modus auf einem Gerät unterstützt wird, überprüfen Sie, ob die OpticalImageStabilizationControl.SupportedModes-Auflistung den gewünschten Modus enthält.

Aktivieren oder deaktivieren Sie OIS, indem Sie die OpticalImageStabilizationControl.Mode auf den gewünschten Modus festlegen.

private void SetOpticalImageStabilizationMode(OpticalImageStabilizationMode mode)
{
    if (!m_mediaCapture.VideoDeviceController.OpticalImageStabilizationControl.Supported)
    {
        tbStatus.Text = "Optical image stabilization not available";
        return;
    }

    var stabilizationModes = m_mediaCapture.VideoDeviceController.OpticalImageStabilizationControl.SupportedModes;

    if (!stabilizationModes.Contains(mode))
    {
        tbStatus.Text = "Optical image stabilization setting not supported";
        return;
    }

    m_mediaCapture.VideoDeviceController.OpticalImageStabilizationControl.Mode = mode;
}

Netzleitungsfrequenz

Einige Kamerageräte unterstützen die Antiflimmerverarbeitung, die davon abhängt, dass sie die Ac-Frequenz der Netzleitungen in der aktuellen Umgebung kennen. Einige Geräte unterstützen die automatische Bestimmung der Netzleitungsfrequenz, während andere die Manuelle Festlegung der Frequenz erfordern. Das folgende Codebeispiel zeigt, wie Sie die Unterstützung der Netzleitungsfrequenz auf dem Gerät ermitteln und bei Bedarf die Häufigkeit manuell festlegen.

Rufen Sie zunächst die methode VideoDeviceController method TryGetPowerlineFrequency auf, Übergeben eines Ausgabeparameters vom Typ PowerlineFrequency; Wenn dieser Aufruf fehlschlägt, wird das Netzleitungsfrequenzsteuerelement auf dem aktuellen Gerät nicht unterstützt. Wenn das Feature unterstützt wird, können Sie ermitteln, ob der automatische Modus auf dem Gerät verfügbar ist, indem Sie versuchen, den automatischen Modus festzulegen. Rufen Sie dazu TrySetPowerlineFrequency auf und übergeben Sie den Wert Auto. Wenn der Aufruf erfolgreich ist, bedeutet dies, dass die automatische Netzfrequenz unterstützt wird. Wenn der Stromleitungsfrequenzcontroller auf dem Gerät unterstützt wird, die automatische Frequenzerkennung jedoch nicht ist, können Sie die Häufigkeit trotzdem manuell mithilfe von TrySetPowerlineFrequency festlegen. In diesem Beispiel ist MyCustomFrequencyLookup eine benutzerdefinierte Methode, die Sie implementieren, um die richtige Häufigkeit für die aktuelle Position des Geräts zu bestimmen.

PowerlineFrequency getFrequency;

if (!m_mediaCapture.VideoDeviceController.TryGetPowerlineFrequency(out getFrequency))
{
    // Powerline frequency is not supported on this device.
    return;
}

if (!m_mediaCapture.VideoDeviceController.TrySetPowerlineFrequency(PowerlineFrequency.Auto))
{
    // Set the frequency manually.
    PowerlineFrequency setFrequency = MyCustomFrequencyLookup();
    if (m_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 festlegen, der während der Foto- oder Videoaufnahme verwendet wird.

In diesem Beispiel wird ein ComboBox-Steuerelement verwendet, um aus integrierten Farbtemperaturvoreinstellungen und einem Schieberegler-Steuerelement für die manuelle Anpassung des Weißabgleichs auszuwählen.

<Slider Name="slWhiteBalance" ValueChanged="slWhiteBalance_ValueChanged"/>
<TextBlock Name="tbWhiteBalance" Text="{Binding ElementName=slWhiteBalance,Path=Value}" Visibility="{Binding ElementName=slWhiteBalance,Path=Visibility}"/>
<ComboBox Name="cbWhiteBalance" SelectionChanged="cbWhiteBalance_SelectionChanged"/>

Überprüfen Sie, ob das aktuelle Aufnahmegerät whiteBalanceControl unterstützt, indem Sie die unterstützte Eigenschaft überprüfen. Wenn das Steuerelement unterstützt wird, können Sie die Benutzeroberfläche für dieses Feature anzeigen und aktivieren. Legen Sie die Elemente des Kombinationsfelds auf die Werte der ColorTemperaturePresetAufzählung fest. Und legen Sie das ausgewählte Element auf den aktuellen Wert der Preset-Eigenschaft fest.

Bei der manuellen Steuerung muss der Wert für den Weißabgleich innerhalb des vom Gerät unterstützten Bereichs liegen und eine Inkrementierung der unterstützten Schrittgröße 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 Schiebereglersteuerelements verwendet werden. Überprüfen Sie vor dem Aktivieren der manuellen Steuerung, ob der Bereich zwischen den minimalen und den maximal unterstützten Werten größer als die Schrittgröße ist. Wenn dies nicht der Grund ist, wird die manuelle Steuerung auf dem aktuellen Gerät nicht unterstützt.

Legen Sie den Wert des Schieberegler-Steuerelements auf den aktuellen Wert von WhiteBalanceControl fest, nachdem Sie die Registrierung des ValueChanged-Ereignishandlers aufgehoben haben , sodass das Ereignis beim Festlegen des Werts nicht ausgelöst wird.

var whiteBalanceControl = m_mediaCapture.VideoDeviceController.WhiteBalanceControl;

if (whiteBalanceControl.Supported)
{
    slWhiteBalance.Visibility = Visibility.Visible;
    cbWhiteBalance.Visibility = Visibility.Visible;

    if (cbWhiteBalance.ItemsSource == null)
    {
        cbWhiteBalance.ItemsSource = Enum.GetValues(typeof(ColorTemperaturePreset)).Cast<ColorTemperaturePreset>();
    }

    cbWhiteBalance.SelectedItem = whiteBalanceControl.Preset;

    if (whiteBalanceControl.Max - whiteBalanceControl.Min > whiteBalanceControl.Step)
    {
        slWhiteBalance.Minimum = whiteBalanceControl.Min;
        slWhiteBalance.Maximum = whiteBalanceControl.Max;
        slWhiteBalance.StepFrequency = whiteBalanceControl.Step;

        slWhiteBalance.ValueChanged -= slWhiteBalance_ValueChanged;
        slWhiteBalance.Value = whiteBalanceControl.Value;
        slWhiteBalance.ValueChanged += slWhiteBalance_ValueChanged;
    }
    else
    {
        slWhiteBalance.Visibility = Visibility.Collapsed;
    }
}
else
{
    slWhiteBalance.Visibility = Visibility.Collapsed;
    cbWhiteBalance.Visibility = Visibility.Collapsed;
}

Rufen Sie im SelectionChanged-Ereignishandler des Kombinationsfelds für die Farbtemperaturvoreinstellung die aktuell ausgewählte Voreinstellung ab, und legen Sie den Wert des Steuerelements fest, indem Sie SetPresetAsync aufrufen. Wenn der ausgewählte voreingestellte Wert nicht manuell ist, deaktivieren Sie den Schieberegler für den manuellen Weißabgleich.

private async void cbWhiteBalance_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if(!m_isPreviewing)
    {
        // Do not set white balance values unless the preview stream is running.
        return;
    }

    var selected = (ColorTemperaturePreset)cbWhiteBalance.SelectedItem;
    slWhiteBalance.IsEnabled = (selected == ColorTemperaturePreset.Manual);
    await m_mediaCapture.VideoDeviceController.WhiteBalanceControl.SetPresetAsync(selected);

}

Rufen Sie im ValueChanged-Ereignishandler den aktuellen Wert des Steuerelements ab, und legen Sie den Wert für den Weißabgleich fest, indem Sie SetValueAsync aufrufen.

private async void slWhiteBalance_ValueChanged(object sender, Microsoft.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
{
    if (!m_isPreviewing)
    {
        // Do not set white balance values unless the preview stream is running.
        return;
    }

    var value = (sender as Slider).Value;
    await m_mediaCapture.VideoDeviceController.WhiteBalanceControl.SetValueAsync((uint)value);
}

Important

Der Weißabgleich kann nur angepasst werden, während der Vorschaustrom aktiv ist. Stellen Sie sicher, dass der Vorschaustream läuft, bevor Sie den Weißabgleichswert oder die Voreinstellung festlegen.

Important

Der Voreinstellungswert ColorTemperaturePreset.Auto weist das System an, den Weißabgleich automatisch anzupassen. Für einige Szenarien, z. B. das Aufnehmen einer Fotosequenz, bei der die Weißabgleichsebenen für jeden Frame identisch sein sollten, sollten Sie das Steuerelement auf den aktuellen automatischen Wert sperren. Rufen Sie dazu SetPresetAsync auf, und geben Sie die manuelle Voreinstellung an, und legen Sie keinen Wert für das Steuerelement mithilfe von SetValueAsync fest. Dadurch fixiert das Gerät den aktuellen Wert. Versuchen Sie nicht, den aktuellen Steuerelementwert zu lesen, und übergeben Sie dann den zurückgegebenen Wert an SetValueAsync , da dieser Wert nicht garantiert korrekt ist.

Zoomen

Mit dem ZoomControl können Sie den Zoomfaktor festlegen, der während der Foto- oder Videoaufnahme verwendet wird.

In diesem Beispiel wird ein Schieberegler-Steuerelement verwendet, um den aktuellen Zoomfaktor anzupassen. Im folgenden Abschnitt wird gezeigt, wie Sie den Zoom basierend auf einer Zusammendrückbewegung auf dem Bildschirm anpassen.

<Slider Name="slZoom" Grid.Row="0" Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Stretch" ValueChanged="slZoom_ValueChanged"/>
<TextBlock Grid.Row="1" HorizontalAlignment="Center" Text="{Binding ElementName=slZoom,Path=Value}"/>
<Button x:Name="bRegisterPinchGestureHandler" Content="Register pinch gesture handler" Click="bRegisterPinchGestureHandler_Click"/>

Überprüfen Sie, ob das aktuelle Aufnahmegerät zoomControl unterstützt, indem Sie die unterstützte Eigenschaft überprüfen. Wenn das Steuerelement unterstützt wird, können Sie die Benutzeroberfläche für dieses Feature anzeigen und aktivieren.

Der Zoomfaktorwert muss sich innerhalb des vom Gerät unterstützten Bereichs befinden und muss ein Inkrement der unterstützten Schrittgröße 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 Schiebereglersteuerelements verwendet werden.

Legen Sie den Wert des Schieberegler-Steuerelements auf den aktuellen Wert von ZoomControl fest, nachdem Sie die Registrierung des ValueChanged-Ereignishandlers aufgehoben haben , sodass das Ereignis beim Festlegen des Werts nicht ausgelöst wird.

var zoomControl = m_mediaCapture.VideoDeviceController.ZoomControl;

if (zoomControl.Supported)
{
    slZoom.Visibility = Visibility.Visible;

    slZoom.Minimum = zoomControl.Min;
    slZoom.Maximum = zoomControl.Max;
    slZoom.StepFrequency = zoomControl.Step;

    slZoom.ValueChanged -= slZoom_ValueChanged;
    slZoom.Value = zoomControl.Value;
    slZoom.ValueChanged += slZoom_ValueChanged;
}
else
{
    slZoom.Visibility = Visibility.Collapsed;
}

Im ereignishandler ValueChanged Erstellen Sie eine neue Instanz der ZoomSettings Klasse, und legen Sie die Value-Eigenschaft auf den aktuellen Wert des Zoomschieberegler-Steuerelements fest. Wenn die SupportedModes-Eigenschaft der ZoomControlZoomTransitionMode.Smooth enthält, dies bedeutet, dass das Gerät reibungslose Übergänge zwischen Zoomstufen unterstützt. Da diese Modi eine bessere Benutzererfahrung bieten, sollten Sie diesen Wert in der Regel für die Mode-Eigenschaft des ZoomSettings-Objekts verwenden.

Ändern Sie schließlich die aktuellen Zoomeinstellungen, indem Sie Ihr ZoomSettings-Objekt an die Configure-Methode des ZoomControl-Objekts übergeben.

private void slZoom_ValueChanged(object sender, Microsoft.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
{
    var level = (float)slZoom.Value;
    var settings = new ZoomSettings { Value = level };

    var zoomControl = m_mediaCapture.VideoDeviceController.ZoomControl;
    if (zoomControl.SupportedModes.Contains(ZoomTransitionMode.Smooth))
    {
        settings.Mode = ZoomTransitionMode.Smooth;
    }
    else
    {
        settings.Mode = zoomControl.SupportedModes.First();
    }

    zoomControl.Configure(settings);
}

Sanftes Zoomen mit der Pinch-Geste

Wie im vorherigen Abschnitt erläutert, ermöglicht der sanfte Zoommodus auf Geräten, die ihn unterstützen, dem Erfassungsgerät einen fließenden Übergang zwischen digitalen Zoomstufen, sodass der Benutzer den Zoomfaktor während des Aufnahmevorgangs dynamisch anpassen kann, ohne diskrete und störende Übergänge in Kauf nehmen zu müssen. In diesem Abschnitt wird beschrieben, wie Sie den Zoomfaktor als Reaktion auf eine Zusammendrückbewegung anpassen.

Ermitteln Sie zunächst, ob das Digitale Zoom-Steuerelement auf dem aktuellen Gerät unterstützt wird, indem Sie die ZoomControl.Supported-Eigenschaft überprüfen. Ermitteln Sie als Nächstes, ob der Modus für den reibungslosen Zoom verfügbar ist, indem Sie den ZoomControl.SupportedModes überprüfen, ob er den Wert ZoomTransitionMode.Smooth enthält.

private bool IsSmoothZoomSupported()
{
    if (!m_mediaCapture.VideoDeviceController.ZoomControl.Supported)
    {
        tbStatus.Text = "Digital zoom is not supported on this device.";
        return false;
    }

    var zoomModes = m_mediaCapture.VideoDeviceController.ZoomControl.SupportedModes;

    if (!zoomModes.Contains(ZoomTransitionMode.Smooth))
    {
        tbStatus.Text = "Smooth zoom not supported";
        return false;
    }

    return true;
}

Auf einem Gerät mit Multitouchfunktion besteht ein typisches Szenario darin, den Zoomfaktor basierend auf einer Zusammendrückbewegung mit zwei Fingern anzupassen. Legen Sie die ManipulationMode-Eigenschaft des CaptureElement-Steuerelements auf ManipulationModes.Scale fest, um die Pinchgeste zu aktivieren. Registrieren Sie sich anschließend für das ManipulationDelta-Ereignis, das ausgelöst wird, wenn die Pinchgeste ihre Größe ändert.

private void RegisterPinchGestureHandler()
{
    if (!IsSmoothZoomSupported())
    {
        return;
    }

    // Enable pinch/zoom gesture for the MediaCaptureElement
    mpePreview.ManipulationMode = ManipulationModes.Scale;
    mpePreview.ManipulationDelta += MpePreview_ManipulationDelta;
}

Aktualisieren Sie im Handler für das ManipulationDelta-Ereignis den Zoomfaktor basierend auf der Änderung der Zusammendrückbewegung des Benutzers. Der ManipulationDelta.Scale-Wert stellt die Änderung des Skalierungsfaktors der Pinchgeste dar, sodass eine leichte Vergrößerung der Pinchgeste einer Zahl entspricht, die geringfügig größer als 1,0 ist, und eine leichte Verkleinerung der Pinchgeste einer Zahl entspricht, die geringfügig kleiner als 1,0 ist. In diesem Beispiel wird der aktuelle Wert des Zoomsteuerelements mit dem Skalierungsdelta multipliziert.

Bevor Sie den Zoomfaktor festlegen, müssen Sie sicherstellen, dass der Wert nicht kleiner als der vom Gerät unterstützte Mindestwert ist, wie durch die ZoomControl.Min-Eigenschaft angegeben. Stellen Sie außerdem sicher, dass der Wert kleiner oder gleich dem ZoomControl.Max-Wert ist. Schließlich müssen Sie sicherstellen, dass der Zoomfaktor ein Vielfaches der Zoomschrittgröße ist, die vom Gerät unterstützt wird, wie durch die Step-Eigenschaft angegeben. Wenn der Zoomfaktor diese Anforderungen nicht erfüllt, wird eine Ausnahme ausgelöst, wenn Sie versuchen, den Zoomfaktor auf dem Aufnahmegerät festzulegen.

Legen Sie den Zoomfaktor auf dem Aufnahmegerät fest, indem Sie ein neues ZoomSettings-Objekt erstellen. Legen Sie die Eigenschaft Mode auf ZoomTransitionMode.Smooth fest und legen Sie dann die Eigenschaft Value auf den gewünschten Zoomfaktor fest. Rufen Sie schließlich ZoomControl.Configure auf, um den neuen Zoomwert auf dem Gerät festzulegen. Das Gerät wechselt reibungslos zum neuen Zoomwert.

private void MpePreview_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
    var zoomControl = m_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;

    m_mediaCapture.VideoDeviceController.ZoomControl.Configure(settings);

}