Pobierz klatkę podglądu z kamery

W tym artykule pokazano, jak przechwycić pojedynczą klatkę podglądu ze strumienia podglądu kamery w aplikacji klasycznej WinUI 3. Ramki podglądu można używać do lekkiej analizy obrazów, takiej jak skanowanie kodów kreskowych lub wykrywanie twarzy, bez rejestrowania pełnego zdjęcia.

Wymagania wstępne

W tym artykule założono, że zainicjowano instancję MediaCapture i uruchomiono podgląd z kamery. Aby uzyskać szczegółowe informacje , zobacz Wyświetlanie podglądu aparatu w aplikacji WinUI lub Dostęp do podglądu aparatu .

Uzyskaj klatkę podglądu jako obiekt SoftwareBitmap

Wywołaj metodę GetPreviewFrameAsync , aby pobrać pojedynczą ramkę ze strumienia podglądu. Możesz przekazać pusty element VideoFrame, aby otrzymać ramkę w bieżącym formacie strumienia podglądu, albo element VideoFrame z określonym formatem pikseli.

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

Możesz również wywołać GetPreviewFrameAsync bez parametrów, aby uzyskać ramkę w formacie natywnym:

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

Wyświetlanie ramki podglądu w interfejsie użytkownika

Aby wyświetlić przechwyconą klatkę w kontrolce Image, przekonwertuj ją na 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;
    });
}

Ważna

W WinUI 3 SoftwareBitmapSource znajduje się w przestrzeni nazw Microsoft.UI.Xaml.Media.Imaging, a nie Windows.UI.Xaml.Media.Imaging. Użyj DispatcherQueue.TryEnqueue, aby zaktualizować interfejs użytkownika, a nie CoreDispatcher.RunAsync.

Przetwórz ramkę podglądu

Po uzyskaniu elementu SoftwareBitmapmożna go przetworzyć przy użyciu dowolnej biblioteki analizy obrazów. Można na przykład użyć wbudowanych interfejsów API Windows do wykrywania twarzy:

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

Wskazówka

Po przetworzeniu należy niezwłocznie usunąć VideoFrame i SoftwareBitmap, aby zwolnić bazowe bufory pamięci.