Condividi tramite


Controlli della fotocamera manuali per l'acquisizione di foto e video

Questo articolo illustra come usare i controlli manuali dei dispositivi per abilitare scenari avanzati di acquisizione di foto e video, tra cui la stabilizzazione ottica delle immagini e lo zoom uniforme.

I controlli descritti in questo articolo vengono tutti aggiunti all'app usando lo stesso modello. Prima di tutto, verificare se il controllo è supportato nel dispositivo corrente in cui è in esecuzione l'app. Se il controllo è supportato, impostare la modalità desiderata per il controllo . In genere, se un particolare controllo non è supportato nel dispositivo corrente, è necessario disabilitare o nascondere l'elemento dell'interfaccia utente che consente all'utente di abilitare la funzionalità.

Il codice in questo articolo è stato adattato dall'esempio SDK di controlli manuali di Fotocamera.. È possibile scaricare questo esempio per visualizzare il codice usato nel contesto o per usare gli esempi come punto di partenza per la propria app.

Nota

Questo articolo si basa sui concetti e sul codice descritti in Acquisizione di foto, video e audio di base con MediaCapture, che descrive i passaggi necessari per implementare l'acquisizione di foto e video di base. È consigliabile acquisire familiarità con il modello di acquisizione multimediale di base in questo articolo prima di passare a scenari di acquisizione più avanzati. Il codice in questo articolo presuppone che l'app abbia già un'istanza di MediaCapture che è stata inizializzata correttamente.

Tutte le API di controllo del dispositivo descritte in questo articolo sono membri dello spazio dei nomi Windows.Media.Devices.

using Windows.Media.Devices;

Esposizione

ExposureControl consente di impostare la velocità dell'otturatore utilizzata durante l'acquisizione di foto o video.

In questo esempio viene utilizzato un controllo Slider per regolare il valore di esposizione corrente e una casella di controllo per attivare o disattivare la regolazione automatica dell'esposizione.

<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"/>

Verificare se il dispositivo di acquisizione corrente supporta ExposureControl controllando la proprietà Supportata. Se il controllo è supportato, è possibile visualizzare e abilitare l'interfaccia utente per questa funzionalità. Impostare lo stato selezionato della casella di controllo per indicare se la regolazione automatica dell'esposizione è attualmente attiva sul valore della proprietà Auto.

Il valore di esposizione deve essere compreso nell'intervallo supportato dal dispositivo e deve essere un incremento delle dimensioni del passaggio supportate. Ottenere i valori supportati per il dispositivo corrente controllando le proprietà Min, Max e Step, usate per impostare le proprietà corrispondenti del controllo dispositivo di scorrimento.

Impostare il valore del controllo dispositivo di scorrimento sul valore corrente di ExposureControl dopo aver annullato la registrazione del gestore eventi ValueChanged in modo che l'evento non venga attivato quando viene impostato il valore.

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

Nel gestore dell'evento ValueChanged ottenere il valore corrente del controllo e impostare il valore di esposizione chiamando 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);
}

Nel gestore eventi CheckedChanged della casella di controllo esposizione automatica attivare o disattivare la regolazione automatica dell'esposizione chiamando SetAutoAsync e passando un valore booleano.

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

Importante

La modalità di esposizione automatica è supportata solo durante l'esecuzione del flusso di anteprima. Verificare che il flusso di anteprima sia in esecuzione prima di attivare l'esposizione automatica.

Compensazione dell'esposizione

ExposureCompensationControl consente di impostare la compensazione dell'esposizione usata durante l'acquisizione di foto o video.

In questo esempio viene usato un controllo Slider per regolare il valore di compensazione dell'esposizione corrente.

<Slider Name="EvSlider" ValueChanged="EvSlider_ValueChanged"/>
<TextBlock Text="{Binding ElementName=EvSlider,Path=Value}" Name="EvTextBlock"/>

Verificare se il dispositivo di acquisizione corrente supporta ExposureCompensationControl controllando la proprietà Supportata. Se il controllo è supportato, è possibile visualizzare e abilitare l'interfaccia utente per questa funzionalità.

Il valore di compensazione esposizione deve essere compreso nell'intervallo supportato dal dispositivo e deve essere un incremento delle dimensioni del passaggio supportate. Ottenere i valori supportati per il dispositivo corrente controllando le proprietà Min, Max e Step, usate per impostare le proprietà corrispondenti del controllo dispositivo di scorrimento.

Impostare il valore del controllo dispositivo di scorrimento sul valore corrente di ExposureCompensationControl dopo aver annullato la registrazione del gestore eventi ValueChanged in modo che l'evento non venga attivato quando viene impostato il valore.

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

Nel gerstore dell'evento ValueChanged ottenere il valore corrente del controllo e impostare il valore di esposizione chiamando 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

FlashControl consente di abilitare o disabilitare il flash o di abilitare il flash automatico, dove il sistema determina in modo dinamico se utilizzare il flash. Questo controllo consente anche di abilitare la riduzione automatica degli occhi rossi nei dispositivi che lo supportano. Queste impostazioni si applicano tutte all'acquisizione di foto. TorchControl è un controllo separato per attivare o disattivare la torcia per l'acquisizione video.

In questo esempio viene usato un set di pulsanti di opzione per consentire all'utente di passare dalle impostazioni di accensione, disattivazione e flash automatico. Viene inoltre fornita una casella di controllo per consentire la disattivazione della riduzione degli occhi rossi e la torcia video.

<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"/>

Verificare se il dispositivo di acquisizione corrente supporta FlashControl controllando la proprietà Supportata. Se il controllo è supportato, è possibile visualizzare e abilitare l'interfaccia utente per questa funzionalità. Se FlashControl è supportato, la riduzione automatica degli occhi rossi può essere supportata o meno, quindi controllare la proprietà RedEyeReductionSupported prima di abilitare l'interfaccia utente. Poiché TorchControl è separato dal controllo flash, è necessario controllare anche la relativa proprietà Supportata prima di usarla.

Nel gestore eventi Selezionato per ognuno dei pulsanti di opzione flash abilitare o disabilitare l'impostazione flash corrispondente appropriata. Si noti che per impostare il flash su sempre da utilizzare, è necessario impostare la proprietà Enabled su true e la proprietà Auto su false.

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

Nel gestore della casella di controllo per la riduzione degli occhi rossi impostare la proprietà pedEyeReduction sul valore appropriato.

private void RedEyeFlashCheckBox_CheckedChanged(object sender, RoutedEventArgs e)
{
    _mediaCapture.VideoDeviceController.FlashControl.RedEyeReduction = (RedEyeFlashCheckBox.IsChecked == true);
}

Infine, nel gestore per la casella di controllo della torcia video impostare la proprietà Enabled sul valore appropriato.

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

Nota

In alcuni dispositivi la torcia non emetterà luce, anche se TorchControl.Enabled è impostato su true, a meno che il dispositivo non abbia un flusso di anteprima in esecuzione e acquisisca attivamente video. L'ordine consigliato per le operazioni consiste nell'attivare l'anteprima video, attivare la torcia impostando Abilitato su true e quindi avviare l'acquisizione video. In alcuni dispositivi la torcia si accenderà dopo l'avvio dell'anteprima. In altri dispositivi, la torcia potrebbe non accendersi fino all'avvio dell'acquisizione video.

Focus

Tre diversi metodi comunemente usati per regolare lo stato attivo della fotocamera sono supportati dall'oggetto FocusControl, dall'autofocus continuo, dal tocco per lo stato attivo e dallo stato attivo manuale. Un'app fotocamera può supportare tutti e tre questi metodi, ma per la leggibilità, questo articolo illustra ogni tecnica separatamente. Questa sezione illustra anche come abilitare la luce di supporto dello stato attivo.

Autofocus continuo

L'abilitazione dell'autofocus continuo indica alla fotocamera di regolare dinamicamente lo stato attivo per cercare di mantenere il soggetto della foto o del video nello stato attivo. In questo esempio viene usato un pulsante di opzione per attivare e disattivare l'autofocus continuo.

<RadioButton Content="CAF" Name="CafFocusRadioButton" Checked="CafFocusRadioButton_Checked"/>

Verificare se il dispositivo di acquisizione corrente supporta FocusControl controllando la proprietà Supportata. Determinare quindi se l'autofocus continuo è supportato controllando l'elenco SupportedFocusModes per verificare se contiene il valore FocusMode.Continuous e, in tal caso, visualizzare il pulsante di opzione autofocus continuo.

var focusControl = _mediaCapture.VideoDeviceController.FocusControl;

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

Nel gestore eventi selezionato per il pulsante di opzione autofocus continuo utilizzare la proprietà VideoDeviceController.FocusControl per ottenere un'istanza del controllo. Chiamare UnlockAsync per sbloccare il controllo nel caso in cui l'app abbia precedentemente chiamato LockAsync per abilitare una delle altre modalità di messa a fuoco.

Creare un nuovo oggetto FocusSettings e impostare la proprietà Mode su Continuo. Impostare la proprietà AutoFocusRange su un valore appropriato per lo scenario dell'app o selezionato dall'utente dall'interfaccia utente. Passare l'oggetto FocusSettings nel metodo Configure, quindi chiamare FocusAsync per avviare l'autofocus continuo.

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

Importante

La modalità autofocus è supportata solo durante l'esecuzione del flusso di anteprima. Verificare che il flusso di anteprima sia in esecuzione prima di attivare l'autofocus continuo.

Toccare per concentrarsi

La tecnica tap-to-focus usa FocusControl e RegionsOfInterestControl per specificare un'area secondaria del fotogramma di acquisizione in cui il dispositivo di acquisizione deve concentrarsi. L'area dello stato attivo è determinata dall'utente che tocca sullo schermo che visualizza il flusso di anteprima.

In questo esempio viene usato un pulsante di opzione per abilitare e disabilitare la modalità tocco/messa a fuoco.

<RadioButton Content="Tap" Name="TapFocusRadioButton" Checked="TapFocusRadioButton_Checked"/>

Verificare se il dispositivo di acquisizione corrente supporta FocusControl controllando la proprietà Supportata. Per usare questa tecnica, è necessario supportare RegionsOfInterestControl e deve supportare almeno un'area. Controllare le proprietà AutoFocusSupported e MaxRegions per determinare se visualizzare o nascondere il pulsante di opzione per lo stato attivo.

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

Nel gestore eventi selezionato per il pulsante di opzione tap-to-focus continuo utilizzare la proprietà VideoDeviceController.FocusControl per ottenere un'istanza del controllo. Chiamare LockAsync per bloccare il controllo nel caso in cui l'app abbia precedentemente chiamato UnlockAsync per abilitare l'autofocus continuo e quindi attendere che l'utente tocchi lo schermo per modificare lo stato attivo.

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
}

Questo esempio è incentrato su un'area quando l'utente tocca lo schermo e quindi rimuove lo stato attivo da tale area quando l'utente tocca di nuovo, ad esempio un interruttore. Usare una variabile booleana per tenere traccia dello stato attivato/disattivato corrente.

bool _isFocused = false;

Il passaggio successivo consiste nell'ascoltare l'evento quando l'utente tocca lo schermo gestendo l'evento Tapped di CaptureElement che attualmente visualizza il flusso di anteprima di acquisizione. Se la fotocamera non è attualmente in anteprima o se la modalità tocco a fuoco è disabilitata, tornare dal gestore senza eseguire alcuna operazione.

Se la variabile di rilevamento _isFocused è impostata su false e se la fotocamera non è attualmente in fase di messa a fuoco (determinata dalla proprietà FocusState di FocusControl), iniziare il processo tap-to-focus. Ottenere la posizione del tocco dell'utente dagli argomenti dell'evento passati al gestore. In questo esempio viene usata anche questa opportunità per selezionare le dimensioni dell'area su cui verrà eseguita l'attenzione. In questo caso, la dimensione è 1/4 della dimensione più piccola dell'elemento capture. Passare la posizione del tocco e le dimensioni dell'area nel metodo helper TapToFocus definito nella sezione successiva.

Se l'interruttore _isFocused è impostato su true, il tocco dell'utente deve cancellare lo stato attivo dall'area precedente. Questa operazione viene eseguita nel metodo helper TapUnfocus illustrato di seguito.

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

Nel metodo helper TapToFocus impostare prima di tutto l'interruttore _isFocused su true in modo che il tocco dello schermo successivo rilasci lo stato attivo dall'area toccata.

L'attività successiva in questo metodo helper consiste nel determinare il rettangolo all'interno del flusso di anteprima che verrà assegnato al controllo dello stato attivo. Questo richiede due passaggi. Il primo passaggio consiste nel determinare il rettangolo che il flusso di anteprima occupa all'interno del controllo CaptureElement. Questo dipende dalle dimensioni del flusso di anteprima e dall'orientamento del dispositivo. Il metodo helper GetPreviewStreamRectInControl, illustrato alla fine di questa sezione, esegue questa attività e restituisce il rettangolo contenente il flusso di anteprima.

L'attività successiva TapToFocus consiste nel convertire la posizione del tocco e le dimensioni desiderate del rettangolo di attivazione, determinate all'interno del gestore eventi CaptureElement.Tapped in coordinate all'interno del flusso di acquisizione. Il metodo helper ConvertUiTapToPreviewRect, illustrato più avanti in questa sezione, esegue questa conversione e restituisce il rettangolo, nelle coordinate del flusso di acquisizione, in cui verrà richiesto lo stato attivo.

Ora che il rettangolo di destinazione è stato ottenuto, creare un nuovo oggetto RegionOfInterest, impostando Bounds sul rettangolo bersaglio ottenuto nei passaggi precedenti.

Ottenere FocusControl del dispositivo di acquisizione. Creare un nuovo oggetto FocusSettings e impostare Modalità e AutoFocusRange ai valori desiderati, dopo essersi assicurati che siano supportati da FocusControl. Chiamare Configure su FocusControl per attivare le impostazioni e segnalare al dispositivo di iniziare a concentrarsi sull'area specificata.

Ottenere quindi le aree del dispositivo di acquisizione RegionsOfInterestControl e chiamare SetRegionsAsync per impostare l'area attiva. È possibile impostare più aree di interesse nei dispositivi che lo supportano, ma in questo esempio viene impostata solo una singola area.

Infine, chiamare FocusAsync su FocusControl per avviare la messa a fuoco.

Importante

Quando si implementa il tocco per lo stato attivo, l'ordine delle operazioni è importante. È consigliabile chiamare queste API nell'ordine seguente:

  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 = _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();
}

Nel metodo helper TapUnfocus , ottenere RegionsOfInterestControl e chiamare ClearRegionsAsync per cancellare l'area registrata con il controllo all'interno del metodo helper TapToFocus. Quindi, ottenere FocusControl e chiamare FocusAsync per fare in modo che il dispositivo venga rifocus senza un'area di interesse.

private async Task TapUnfocus()
{
    _isFocused = false;

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

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

Il metodo helper GetPreviewStreamRectInControl usa la risoluzione del flusso di anteprima e l'orientamento del dispositivo per determinare il rettangolo all'interno dell'elemento di anteprima che contiene il flusso di anteprima, rimuovendo qualsiasi riempimento in formato letterboxing che il controllo può fornire per mantenere le proporzioni del flusso. Questo metodo usa le variabili membro della classe definite nel codice di esempio di acquisizione multimediale di base disponibile in Acquisizione di immagini, video e audio di base con MediaCapture.

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

Il metodo helper ConvertUiTapToPreviewRect accetta come argomenti la posizione dell'evento tap, le dimensioni desiderate dell'area dello stato attivo e il rettangolo contenente il flusso di anteprima ottenuto dal metodo helper GetPreviewStreamRectInControl. Questo metodo usa questi valori e l'orientamento corrente del dispositivo per calcolare il rettangolo all'interno del flusso di anteprima che contiene l'area desiderata. Ancora una volta, questo metodo usa le variabili membro della classe definite nel codice di esempio di acquisizione multimediale di base disponibile in Acquisizione di immagini e video con MediaCapture.

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

Stato attivo manuale

La tecnica di messa a fuoco manuale usa un controllo Slider per impostare la profondità di messa a fuoco corrente del dispositivo di acquisizione. Un pulsante di opzione viene usato per attivare e disattivare lo stato attivo manuale.

<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"/>

Verificare se il dispositivo di acquisizione corrente supporta FocusControl controllando la proprietà Supportata. Se il controllo è supportato, è possibile visualizzare e abilitare l'interfaccia utente per questa funzionalità.

Il valore di focus deve essere compreso nell'intervallo supportato dal dispositivo e deve essere un incremento delle dimensioni del passaggio supportate. Ottenere i valori supportati per il dispositivo corrente controllando le proprietà Min, Max e Step, usate per impostare le proprietà corrispondenti del controllo dispositivo di scorrimento.

Impostare il valore del controllo dispositivo di scorrimento sul valore corrente di FocusControl dopo aver annullato la registrazione del gestore eventi ValueChanged in modo che l'evento non venga attivato quando viene impostato il valore.

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

Nel gestore eventi Controllato per il pulsante di opzione dello stato attivo manuale ottenere l'oggetto FocusControl e chiamare LockAsync nel caso in cui l'app avesse sbloccato in precedenza lo stato attivo con una chiamata a UnlockAsync.

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

Nel gestore dell'evento ValueChanged del dispositivo di scorrimento dello stato attivo manuale ottenere il valore corrente del controllo e impostare il valore dello stato attivo chiamando 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);
}

Abilitare la luce dello stato attivo

Nei dispositivi che lo supportano, è possibile abilitare una luce di assistenza messa a fuoco per aiutare lo stato attivo del dispositivo. In questo esempio viene usata una casella di controllo per abilitare o disabilitare la luce di attivazione dello stato attivo.

<CheckBox Content="Assist Light" Name="FocusLightCheckBox" IsEnabled="{Binding ElementName=TapFocusRadioButton,Path=IsChecked}"
                  Checked="FocusLightCheckBox_CheckedChanged" Unchecked="FocusLightCheckBox_CheckedChanged"/>

Verificare se il dispositivo di acquisizione corrente supporta FlashControl controllando la proprietà Supportata. Controllare anche AssistantLightSupported per assicurarsi che anche la luce di assistenza sia supportata. Se sono entrambi supportati, è possibile visualizzare e abilitare l'interfaccia utente per questa funzionalità.

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

Nel gestore eventi CheckedChanged, ottenere FlashControl dei dispositivi di acquisizione. Impostare la proprietà AssistantLightEnabled per abilitare o disabilitare la luce dello stato attivo.

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

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

Velocità di ISO

IsoSpeedControl consente di impostare la velocità ISO usata durante l'acquisizione di foto o video.

In questo esempio viene utilizzato un controllo Slider per regolare il valore di compensazione dell'esposizione corrente e una casella di controllo per attivare o disattivare la regolazione automatica della velocità ISO.

<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"/>

Verificare se il dispositivo di acquisizione corrente supporta IsoSpeedControl controllando la proprietà Supportata. Se il controllo è supportato, è possibile visualizzare e abilitare l'interfaccia utente per questa funzionalità. Impostare lo stato selezionato della casella di controllo per indicare se la regolazione automatica della velocità ISO è attualmente attiva sul valore della proprietà Auto.

Il valore di velocità ISO deve essere compreso nell'intervallo supportato dal dispositivo e deve essere un incremento delle dimensioni del passaggio supportate. Ottenere i valori supportati per il dispositivo corrente controllando le proprietà Min, Max e Step, usate per impostare le proprietà corrispondenti del controllo dispositivo di scorrimento.

Impostare il valore del controllo dispositivo di scorrimento sul valore corrente di IsoSpeedControl dopo aver annullato la registrazione del gestore eventi ValueChanged in modo che l'evento non venga attivato quando viene impostato il valore.

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

Nel gestore dell'evento ValueChanged ottenere il valore corrente del controllo e impostare il valore di velocità ISO chiamando 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);
}

Nel gestore eventi CheckedChanged della casella di spunta velocità ISO automatica, attivare la regolazione automatica della velocità ISO chiamando SetAutoAsync. Disattivare la regolazione automatica della velocità ISO chiamando SetValueAsync e passando il valore corrente del controllo dispositivo di scorrimento.

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

Stabilizzazione ottica delle immagini

La stabilizzazione ottica delle immagini (OIS) stabilizza il flusso video acquisito manipolando meccanicamente il dispositivo di acquisizione hardware, che può fornire un risultato superiore rispetto alla stabilizzazione digitale. Nei dispositivi che non supportano OIS, è possibile usare VideoStabilizationEffect per eseguire la stabilizzazione digitale nel video acquisito. Per maggiori informazioni, vedere Effetti per l'acquisizione video.

Determinare se OIS è supportato nel dispositivo corrente controllando la proprietà OpticalImageStabilizationControl.Supported.

Il controllo OIS supporta tre modalità: on, off e automatica, il che significa che il dispositivo determina in modo dinamico se OIS migliorerà l'acquisizione multimediale e, in tal caso, abilita OIS. Per determinare se una particolare modalità è supportata in un dispositivo corrente, verificare se l'insieme OpticalImageStabilizationControl.SupportedModes contiene la modalità desiderata.

Abilitare o disabilitare OIS impostando OpticalImageStabilizationControl.Mode sulla modalità desiderata.

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

Frequenza della linea di alimentazione

Alcuni dispositivi fotocamera supportano l'elaborazione anti-sfarfallio che dipende dalla conoscenza della frequenza AC delle linee di alimentazione nell'ambiente corrente. Alcuni dispositivi supportano la determinazione automatica della frequenza di alimentazione, mentre altri richiedono che la frequenza venga impostata manualmente. Nell'esempio di codice seguente viene illustrato come determinare il supporto della frequenza di alimentazione sul dispositivo e, se necessario, come impostare manualmente la frequenza.

Prima di tutto, chiamare il metodo VideoDeviceController TryGetPowerlineFrequency, passando un parametro di output di tipo PowerlineFrequency; se questa chiamata ha esito negativo, il controllo frequenza della linea di alimentazione non è supportato nel dispositivo corrente. Se la funzionalità è supportata, è possibile determinare se la modalità automatica è disponibile nel dispositivo provando a impostare la modalità automatica. Per farlo chiamare TrySetPowerlineFrequency e passare al valore Auto. Se la chiamata ha esito positivo, significa che la frequenza della linea di alimentazione automatica è supportata. Se il controller di frequenza della linea di alimentazione è supportato nel dispositivo, ma il rilevamento automatico della frequenza non è, è comunque possibile impostare manualmente la frequenza usando TrySetPowerlineFrequency. In questo esempio, MyCustomFrequencyLookup è un metodo personalizzato implementato per determinare la frequenza corretta per la posizione corrente del dispositivo.

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

Bilanciamento del bianco

WhiteBalanceControl consente di impostare il bilanciamento del bianco usato durante l'acquisizione di foto o video.

Questo esempio usa un controllo ComboBox per selezionare i set di impostazioni di temperatura dei colori predefiniti e un controllo Slider per la regolazione manuale del bilanciamento del bianco.

<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"/>

Verificare se il dispositivo di acquisizione corrente supporta WhiteBalanceControl controllando la proprietà Supportata. Se il controllo è supportato, è possibile visualizzare e abilitare l'interfaccia utente per questa funzionalità. Impostare gli elementi della casella combinata sui valori dell'enumerazione ColorTemperaturePreset . Impostare l'elemento selezionato sul valore corrente della proprietà Preset.

Per il controllo manuale, il valore di bilanciamento del bianco deve essere compreso nell'intervallo supportato dal dispositivo e deve essere un incremento della dimensione del passaggio supportata. Ottenere i valori supportati per il dispositivo corrente controllando le proprietà Min, Max e Step, usate per impostare le proprietà corrispondenti del controllo dispositivo di scorrimento. Prima di abilitare il controllo manuale, verificare che l'intervallo tra i valori minimo e massimo supportato sia maggiore delle dimensioni del passaggio. In caso contrario, il controllo manuale non è supportato nel dispositivo corrente.

Impostare il valore del controllo a scorrimento sul valore corrente di WhiteBalanceControl dopo aver annullato la registrazione del gestore eventi ValueChanged in modo che l'evento non venga attivato quando viene impostato il valore.

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

Nel gestore di avanti SelectionChanged della casella combinata set di impostazioni di temperatura colore ottenere il set di impostazioni attualmente selezionato e impostare il valore del controllo chiamando SetPresetAsync. Se il valore del set di impostazioni selezionato non è Manuale, disabilitare il dispositivo a scorrimento manuale per il bilanciamento del bianco.

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

}

Nel gestore dell'evento ValueChanged ottenere il valore corrente del controllo e impostare il valore di bilanciamento del bianco chiamando 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);
}

Importante

La regolazione del bilanciamento del bianco è supportata solo durante l'esecuzione del flusso di anteprima. Verificare che il flusso di anteprima sia in esecuzione prima di impostare il valore di bilanciamento del bianco o il set di impostazioni.

Importante

Il valore predefinito ColorTemperaturePreset.Auto indica al sistema di regolare automaticamente il livello di bilanciamento del bianco. Per alcuni scenari, ad esempio l'acquisizione di una sequenza di foto in cui i livelli di bilanciamento del bianco devono essere uguali per ogni fotogramma, è possibile bloccare il controllo sul valore automatico corrente. Per farlo, chiamare SetPresetAsync e specificare la preimpostazione Manual e non impostare un valore nel controllo usando SetValueAsync. In questo modo il dispositivo bloccherà il valore corrente. Non tentare di leggere il valore del controllo corrente e quindi passare il valore restituito in SetValueAsync perché non è garantito che questo valore sia corretto.

Zoom

ZoomControl consente di impostare il livello di zoom usato durante l'acquisizione di foto o video.

In questo esempio viene usato un controllo Slider per regolare il livello di zoom corrente. La sezione seguente illustra come regolare lo zoom in base a un movimento di avvicinamento delle dita sullo schermo.

<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}"/>

Verificare se il dispositivo di acquisizione corrente supporta ZoomControl controllando la proprietà Supportata. Se il controllo è supportato, è possibile visualizzare e abilitare l'interfaccia utente per questa funzionalità.

Il valore di livello di zoom deve essere compreso nell'intervallo supportato dal dispositivo e deve essere un incremento delle dimensioni del passaggio supportate. Ottenere i valori supportati per il dispositivo corrente controllando le proprietà Min, Max e Step, usate per impostare le proprietà corrispondenti del controllo dispositivo di scorrimento.

Impostare il valore del controllo dispositivo di scorrimento sul valore corrente di ZoomControl dopo aver annullato la registrazione del gestore eventi ValueChanged in modo che l'evento non venga attivato quando viene impostato il valore.

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

Nel gestore evento ValueChanged, crea una nuova istanza della classe ZoomSettings, impostando il Valore sul valore corrente del dispositivo di scorrimento dello zoom. Se la proprietà SupportedModes di ZoomControl contiene ZoomTransitionMode.Smooth, significa che il dispositivo supporta transizioni uniformi tra i livelli di zoom. Poiché questa modalità offre un'esperienza utente migliore, in genere si vuole usare questo valore per la proprietà Mode dell'oggetto Zoom Impostazioni.

Modificare infine le impostazioni di zoom correnti passando l'oggetto ZoomSettings nel metodo Configure dell'oggetto ZoomControl.

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

Zoom uniforme usando il movimento di avvicinamento delle dita

Come descritto nella sezione precedente, nei dispositivi che lo supportano, la modalità zoom uniforme consente al dispositivo di acquisizione di passare senza problemi tra i livelli di zoom digitale, consentendo all'utente di regolare dinamicamente il livello di zoom durante l'operazione di acquisizione senza transizioni discrete e jarring. Questa sezione descrive come regolare il livello di zoom in risposta a un movimento di avvicinamento delle dita.

Per prima cosa, determinare se il controllo zoom digitale è supportato nel dispositivo corrente controllando la proprietà ZoomControl.Supported. Determinare quindi se la modalità zoom uniforme è disponibile controllando ZoomControl.SupportedModes per vedere se contiene il valore ZoomTransitionMode.Smooth.

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

In un dispositivo abilitato per il multitocco, uno scenario tipico consiste nel regolare il fattore di zoom in base a un gesto di avvicinamento delle dita a due dita. Impostare la proprietà ManipulationMode del controllo CaptureElement su ManipulationModes.Scale per abilitare il movimento di avvicinamento delle dita. Eseguire quindi la registrazione per l'evento ManipulationDelta che viene generato quando il movimento di avvicinamento delle dita cambia le dimensioni.

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

    // Enable pinch/zoom gesture for the preview control
    PreviewControl.ManipulationMode = ManipulationModes.Scale;
    PreviewControl.ManipulationDelta += PreviewControl_ManipulationDelta;
}

Nel gestore per l'evento ManipulationDelta aggiornare il fattore di zoom in base alla modifica nel movimento di avvicinamento delle dita dell'utente. Il valore ManipulationDelta.Scale rappresenta la modifica della scala del movimento di avvicinamento delle dita in modo che un piccolo aumento delle dimensioni della avvicinamento sia un numero leggermente maggiore di 1,0 e una piccola diminuzione delle dimensioni delle dita è un numero leggermente inferiore a 1,0. In questo esempio il valore corrente del controllo zoom viene moltiplicato per il delta della scala.

Prima di impostare il fattore di zoom, è necessario assicurarsi che il valore non sia inferiore al valore minimo supportato dal dispositivo, come indicato dalla proprietà ZoomControl.Min. Assicurarsi inoltre che il valore sia minore o uguale al valore ZoomControl.Max. Infine, è necessario assicurarsi che il fattore di zoom sia un multiplo delle dimensioni del passaggio di zoom supportate dal dispositivo, come indicato dalla proprietà Step. Se il fattore di zoom non soddisfa questi requisiti, verrà generata un'eccezione quando si tenta di impostare il livello di zoom nel dispositivo di acquisizione.

Impostare il livello di zoom sul dispositivo di acquisizione creando un nuovo oggetto ZoomSettings. Impostare la proprietà Mode a ZoomTransitionMode.Smooth e quindi impostare la proprietà Value al fattore di zoom desiderato. Infine, chiamare ZoomControl.Configure per impostare il nuovo valore di zoom nel dispositivo. Il dispositivo passerà senza problemi al nuovo valore di zoom.

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

}