Obter um quadro de pré-visualização da câmera

Este artigo mostra como capturar um único quadro de visualização do fluxo de visualização da câmera em um aplicativo da área de trabalho do WinUI 3. Você pode usar quadros de visualização para análise de imagem leve, como verificação de código de barras ou detecção facial, sem gravar uma foto completa.

Pré-requisitos

Este artigo pressupõe que você inicializou uma instância do MediaCapture e iniciou uma visualização da câmera. Confira Mostrar a visualização da câmera em um aplicativo WinUI ou acesso de visualização da câmera para obter detalhes.

Obter um quadro de pré-visualização como um SoftwareBitmap

Chame GetPreviewFrameAsync para obter um único quadro do fluxo de visualização. Você pode passar um VideoFrame vazio para receber o quadro no formato atual do fluxo de visualização ou passar um VideoFrame com um formato de pixel específico.

using Windows.Media;
using Windows.Media.Capture;
using Windows.Media.MediaProperties;
using Windows.Graphics.Imaging;

private async Task<SoftwareBitmap> GetPreviewFrameAsSoftwareBitmapAsync()
{
    // Get the preview stream dimensions using VideoEncodingProperties
    var previewProperties =
        _mediaCapture.VideoDeviceController
            .GetMediaStreamProperties(MediaStreamType.VideoPreview)
            as VideoEncodingProperties;

    // Create a VideoFrame to receive the preview frame.
    // VideoFrame implements IDisposable — use a using statement.
    using var previewFrame = new VideoFrame(
        BitmapPixelFormat.Bgra8,
        (int)previewProperties.Width,
        (int)previewProperties.Height);

    await _mediaCapture.GetPreviewFrameAsync(previewFrame);

    // Return a copy of the SoftwareBitmap because the
    // VideoFrame is disposed when this method returns.
    return SoftwareBitmap.Copy(previewFrame.SoftwareBitmap);
}

Você também pode chamar GetPreviewFrameAsync sem parâmetros para obter um quadro no formato nativo:

var previewFrame = await _mediaCapture.GetPreviewFrameAsync();
SoftwareBitmap previewBitmap = previewFrame.SoftwareBitmap;

Exibir o quadro de visualização na interface do usuário

Para exibir o quadro capturado em um controle image , converta-o em um SoftwareBitmapSource:

using Microsoft.UI.Xaml.Media.Imaging;

private async Task DisplayPreviewFrameAsync(
    SoftwareBitmap softwareBitmap)
{
    // SoftwareBitmapSource requires Bgra8 with premultiplied alpha
    if (softwareBitmap.BitmapPixelFormat != BitmapPixelFormat.Bgra8 ||
        softwareBitmap.BitmapAlphaMode != BitmapAlphaMode.Premultiplied)
    {
        softwareBitmap = SoftwareBitmap.Convert(
            softwareBitmap,
            BitmapPixelFormat.Bgra8,
            BitmapAlphaMode.Premultiplied);
    }

    var source = new SoftwareBitmapSource();
    await source.SetBitmapAsync(softwareBitmap);

    // Set the Image control's source on the UI thread
    DispatcherQueue.TryEnqueue(() =>
    {
        PreviewImage.Source = source;
    });
}

Importante

No WinUI 3, SoftwareBitmapSource está no Microsoft.UI.Xaml.Media.Imaging namespace, não Windows.UI.Xaml.Media.Imaging. Use DispatcherQueue.TryEnqueue para atualizar a interface do usuário, não CoreDispatcher.RunAsync.

Processar o quadro de pré-visualização

Depois de obter um SoftwareBitmap, você pode processá-lo com qualquer biblioteca de análise de imagem. Por exemplo, você pode usar Windows APIs internas para detecção facial:

using Windows.Media;

private async Task AnalyzePreviewFrameAsync()
{
    var previewFrame = await _mediaCapture.GetPreviewFrameAsync();
    SoftwareBitmap bitmap = previewFrame.SoftwareBitmap;

    if (bitmap != null)
    {
        // Use the bitmap for image analysis
        // For example, pass it to a face detector or
        // barcode scanner

        bitmap.Dispose();
    }

    previewFrame.Dispose();
}

Dica

Descarte os VideoFrame e SoftwareBitmap após o processamento para liberar prontamente os buffers de memória subjacentes.