本文展示了如何在 WinUI 3 桌面應用程式中,從相機預覽串流中擷取單一預覽畫面。 你可以使用預覽框架進行輕量級影像分析,例如條碼掃描或臉部偵測,而無需錄製完整照片。
先決條件
本文假設你已經初始化了一個 MediaCapture 實例並開始了相機預覽。 詳情請參閱「 在 WinUI 應用程式中顯示相機預覽 」或「 相機預覽權限 」。
取得預覽幀作為 SoftwareBitmap
呼叫 GetPreviewFrameAsync 以取得預覽串流中的單一幀。 你可以傳遞空的 VideoFrame ,以接收預覽串流目前格式的畫面,或是用特定像素格式傳送 VideoFrame 。
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);
}
你也可以不帶參數地呼叫 GetPreviewFrameAsync ,取得原生格式的影格:
var previewFrame = await _mediaCapture.GetPreviewFrameAsync();
SoftwareBitmap previewBitmap = previewFrame.SoftwareBitmap;
在你的介面中顯示預覽幀
若要在 影像 控制中顯示擷取的影格,請將其轉換為 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
在 WinUI 3 中, 是 SoftwareBitmapSource 位於 Microsoft.UI.Xaml.Media.Imaging 命名空間,不是 Windows.UI.Xaml.Media.Imaging。 使用 DispatcherQueue.TryEnqueue 來更新使用者介面,而不是 CoreDispatcher.RunAsync。
處理預覽幀
取得 SoftwareBitmap 後,你可以使用任何影像分析函式庫對其進行處理。 例如,你可以使用 Windows 內建的 API 來進行臉部偵測:
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
處理完成後,請釋放 VideoFrame 和 SoftwareBitmap,以便及時釋放底層記憶體緩衝區。