Get a preview frame
This topic shows you how to get a single preview frame from the media capture preview stream.
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. The 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.
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. 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);
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);
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;
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;
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.
- 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.
- 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.
- 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.
Your app should always check for a null value before trying to operate on the objects returned by the SoftwareBitmap or Direct3DSurface properties.
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. Or, use the using pattern, which automatically disposes of the object.
previewFrame = null;