Hämta en förhandsgranskningsbild från kameran

Den här artikeln visar hur du avbildar en enda förhandsgranskningsram från kamerans förhandsgranskningsström i en WinUI 3-skrivbordsapp. Du kan använda förhandsgranskningsramar för enkel bildanalys, till exempel streckkodsgenomsökning eller ansiktsigenkänning, utan att spela in ett fullständigt foto.

Förutsättningar

Den här artikeln förutsätter att du har initierat en MediaCapture-instans och startat en kameraförhandsgranskning. Mer information finns i Visa kameraförhandsgranskningen i en WinUI-app eller kameraförhandsgranskningsåtkomst .

Hämta en förhandsgranskningsram som en SoftwareBitmap

Anropa GetPreviewFrameAsync för att hämta en enda bildruta från förhandsgranskningsströmmen. Du kan skicka en tom VideoFrame för att ta emot ramen i förhandsgranskningsströmmens aktuella format eller skicka en VideoFrame med ett specifikt pixelformat.

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

Du kan också anropa GetPreviewFrameAsync utan parametrar för att hämta en ram i det interna formatet:

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

Visa förhandsgranskningsramen i användargränssnittet

Om du vill visa den infångade bildrutan i en Image-kontroll konverterar du den till en 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

I WinUI 3 SoftwareBitmapSource finns i Microsoft.UI.Xaml.Media.Imaging namnområdet, inte Windows.UI.Xaml.Media.Imaging. Använd DispatcherQueue.TryEnqueue för att uppdatera användargränssnittet, inte CoreDispatcher.RunAsync.

Bearbeta förhandsgranskningsramen

När du har skaffat en SoftwareBitmapkan du bearbeta den med valfritt bildanalysbibliotek. Du kan till exempel använda Windows inbyggda API:er för ansiktsigenkänning:

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

Kassera VideoFrame och SoftwareBitmap efter bearbetning för att snarast frigöra de underliggande minnesbuffertarna.