Abrufen eines Vorschauframes von der Kamera

In diesem Artikel wird gezeigt, wie Sie einen einzelnen Vorschauframe aus dem Kameravorschaustream in einer WinUI 3-Desktop-App erfassen. Sie können Vorschauframes für eine einfache Bildanalyse verwenden, z. B. Barcodescans oder Gesichtserkennung, ohne ein vollständiges Foto aufzuzeichnen.

Prerequisites

In diesem Artikel wird davon ausgegangen, dass Sie eine MediaCapture-Instanz initialisiert und eine Kameravorschau gestartet haben. Weitere Informationen finden Sie unter "Anzeigen der Kameravorschau" in einer WinUI-App oder einemKameravorschauzugriff .

Ein Vorschaubild als SoftwareBitmap abrufen

Rufen Sie GetPreviewFrameAsync auf, um einen einzelnen Frame aus dem Vorschaudatenstrom abzurufen. Sie können einen leeren VideoFrame übergeben, um den Frame im aktuellen Format des Vorschaustreams zu empfangen, oder einen VideoFrame mit einem bestimmten Pixelformat übergeben.

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

Sie können auch ohne Parameter aufrufen GetPreviewFrameAsync , um einen Frame im systemeigenen Format abzurufen:

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

Zeigen Sie den Vorschaurahmen in Ihrer Benutzeroberfläche an.

Um den aufgenommenen Frame in einem Bildsteuerelement anzuzeigen, konvertieren Sie ihn in eine 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;
    });
}

Important

In WinUI 3 befindet sich SoftwareBitmapSource im Namespace Microsoft.UI.Xaml.Media.Imaging, nicht im Namespace Windows.UI.Xaml.Media.Imaging. Verwenden Sie DispatcherQueue.TryEnqueue, um die Benutzeroberfläche zu aktualisieren, nicht CoreDispatcher.RunAsync.

Verarbeiten des Vorschauframes

Nachdem Sie ein SoftwareBitmapBild abgerufen haben, können Sie ihn mit jeder beliebigen Bildanalysebibliothek verarbeiten. Sie können beispielsweise Windows integrierten APIs für die Gesichtserkennung verwenden:

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

Tip

Entsorgen Sie VideoFrame und SoftwareBitmap nach der Verarbeitung, um die zugrundeliegenden Speicherpuffer zeitnah freizugeben.