取得預覽畫面Get a preview frame

本主題示範如何從媒體擷取預覽資料流取得單一預覽畫面。This topic shows you how to get a single preview frame from the media capture preview stream.

注意

本文是以使用 MediaCapture 進行基本相片、視訊和音訊的擷取中討論的概念和程式碼為基礎,其中說明實作基本相片和視訊擷取的步驟。This article builds on concepts and code discussed in Basic photo, video, and audio capture with MediaCapture, which describes the steps for implementing basic photo and video capture. 我們建議您先熟悉該文章中的基本媒體擷取模式,然後再移到更多進階的擷取案例。We recommend that you familiarize yourself with the basic media capture pattern in that article before moving on to more advanced capture scenarios. 本文中的程式碼假設您的 app 已有正確初始化的 MediaCapture 執行個體,而且您有一個具有使用中視訊預覽資料流的 CaptureElementThe code in this article assumes that your app already has an instance of MediaCapture that has been properly initialized, and that you have a CaptureElement with an active video preview stream.

除了基本媒體擷取所需的命名空間,擷取預覽畫面還需要下列命名空間。In addition to the namespaces required for basic media capture, capturing a preview frame requires the following namespace.

using Windows.Media;

當您要求預覽框架時,您可以使用想要的格式建立 VideoFrame 物件,以指定您要用來接收框架的格式。When you request a preview frame, you can specify the format in which you would like to receive the frame by creating a VideoFrame object with the format you desire. 這個範例會呼叫 VideoDeviceController.GetMediaStreamProperties 並指定 MediaStreamType.VideoPreview 來要求預覽資料流的屬性,以建立與預覽資料流解析度相同的視訊框架。This example creates a video frame that is the same resolution as the preview stream by calling VideoDeviceController.GetMediaStreamProperties and specifying MediaStreamType.VideoPreview to request the properties for the preview stream. 預覽串流的寬度和高度將用來建立新的視訊框架。The width and height of the preview stream is used to create the new video frame.

// Get information about the preview
var previewProperties = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties;

// Create a video frame in the desired format for the preview frame
VideoFrame videoFrame = new VideoFrame(BitmapPixelFormat.Bgra8, (int)previewProperties.Width, (int)previewProperties.Height);

如果您的 MediaCapture 物件已初始化,而且您有使用中的預覽串流,請呼叫 GetPreviewFrameAsync 取得預覽串流。If your MediaCapture object is initialized and you have an active preview stream, call GetPreviewFrameAsync to get a preview stream. 傳入上一個步驟中建立的視訊框架,以指定傳回框架的格式。Pass in the video frame created in the last step to specify the format of the returned frame.

VideoFrame previewFrame = await _mediaCapture.GetPreviewFrameAsync(videoFrame);

存取 VideoFrame 物件的 SoftwareBitmap 屬性,以取得預覽畫面的 SoftwareBitmap 表示。Get a SoftwareBitmap representation of the preview frame by accessing the SoftwareBitmap property of the VideoFrame object. 如需有關儲存、載入和修改軟體點陣圖的資訊,請參閱影像處理For information about saving, loading, and modifying software bitmaps, see Imaging.

SoftwareBitmap previewBitmap = previewFrame.SoftwareBitmap;

如果您想要透過 Direct3D API 使用影像,您也可以取得預覽框架的 IDirect3DSurface 表示。You can also get a IDirect3DSurface representation of the preview frame if you want to use the image with Direct3D APIs.

var previewSurface = previewFrame.Direct3DSurface;

重要

無論是傳回之 VideoFrameSoftwareBitmap 屬性或 Direct3DSurface 屬性,根據您如何呼叫 GetPreviewFrameAsync 以及根據正在執行您 app 的裝置,這些屬性可能會是 Null。Either the SoftwareBitmap property or the Direct3DSurface property of the returned VideoFrame may be null depending on how you call GetPreviewFrameAsync and also depending on the device on which your app is running.

  • 如果您呼叫能接受 VideoFrame 引數之 GetPreviewFrameAsync 的多載,則傳回的 VideoFrame 會有非 Null 的 SoftwareBitmap,且 Direct3DSurface 屬性將會是 Null。If you call the overload of GetPreviewFrameAsync that accepts a VideoFrame argument, the returned VideoFrame will have a non-null SoftwareBitmap and the Direct3DSurface property will be null.
  • 如果您呼叫之 GetPreviewFrameAsync 的多載,在使用 Direct3D 表面於內部呈現畫面的裝置上沒有任何引數,則 Direct3DSurface 屬性將會是非 Null,且 SoftwareBitmap 屬性將會是 Null。If you call the overload of GetPreviewFrameAsync that has no arguments on a device that uses a Direct3D surface to represent the frame internally, the Direct3DSurface property will be non-null and the SoftwareBitmap property will be null.
  • 如果您呼叫之 GetPreviewFrameAsync 的多載,在不使用 Direct3D 表面來在內部代表框架的裝置上沒有任何引數,則 SoftwareBitmap 屬性將會是非 Null,且 Direct3DSurface 屬性將會是 Null。If you call the overload of GetPreviewFrameAsync that has no arguments on a device that does not use a Direct3D surface to represent the frame internally, the SoftwareBitmap property will be non-null and the Direct3DSurface property will be null.

您的 app 在嘗試於 SoftwareBitmapDirect3DSurface 屬性傳回的物件上操作之前,應該先檢查是否有 Null 值。Your app should always check for a null value before trying to operate on the objects returned by the SoftwareBitmap or Direct3DSurface properties.

預覽框架使用完畢後,請務必呼叫其 Close 方法 (對應於 C# 中的 Dispose),以釋放框架使用的資源。When you are done using the preview frame, be sure to call its Close method (projected to Dispose in C#) to free the resources used by the frame. 或者,使用 using 模式來自動處置物件。Or, use the using pattern, which automatically disposes of the object.

previewFrame.Dispose();
previewFrame = null;