Compartir a través de


Obtener un fotograma de vista previa

En este tema se muestra cómo obtener un solo fotograma de vista previa de la secuencia de vista previa de captura multimedia.

Nota

Este artículo se basa en los conceptos y el código analizados en Captura básica de fotos, audio y vídeo con MediaCapture, donde se describen los pasos para implementar la captura básica de fotos y vídeo. Se recomienda que te familiarices con el patrón de captura de multimedia básico de ese artículo antes de pasar a escenarios de captura más avanzados. El código de este artículo supone que la aplicación ya tiene una instancia de MediaCapture que se ha inicializado correctamente y que tienes un objeto CaptureElement con una secuencia de vista previa de vídeo activa.

Además de los espacios de nombres necesarios para realizar la captura multimedia básica, necesitarás el siguiente espacio de nombres para capturar un marco de vista previa.

using Windows.Media;

Al solicitar un marco de vista previa, puedes especificar el formato en el que quieres recibir el marco creando un objeto VideoFrame con el formato que quieras. En este ejemplo se crea un marco de vídeo que tiene la misma la resolución que la secuencia de vista previa; para ello, se ha de llamar al método VideoDeviceController.GetMediaStreamProperties y se debe especificar la enumeración MediaStreamType.VideoPreview para solicitar las propiedades de la secuencia de vista previa. El ancho y alto de la secuencia de vista previa se usa para crear el nuevo marco de vídeo.

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

Si el objeto MediaCapture se inicializa y tiene una secuencia de vista previa activa, llama a GetPreviewFrameAsync para obtener una secuencia de vista previa. Pasa el marco de vídeo creado en el último paso, para especificar el formato del marco devuelto.

VideoFrame previewFrame = await _mediaCapture.GetPreviewFrameAsync(videoFrame);

Consigue una representación de SoftwareBitmap del fotograma de vista previa mediante el acceso a la propiedad SoftwareBitmap del objeto VideoFrame. Para obtener información sobre cómo guardar, cargar y modificar mapas de bits de software, consulta Imágenes.

SoftwareBitmap previewBitmap = previewFrame.SoftwareBitmap;

Asimismo, también puedes obtener una representación de IDirect3DSurface del fotograma de vista previa si quieres usar la imagen con las API de Direct3D.

var previewSurface = previewFrame.Direct3DSurface;

Importante

Es posible que la propiedad SoftwareBitmap o la propiedad Direct3DSurface del valor devuelto de VideoFrame sea nula; todo depende de cómo hayas llamado a GetPreviewFrameAsync y del tipo de dispositivo en el que se ejecute la aplicación.

  • Si llamas a la sobrecarga de GetPreviewFrameAsync que acepta un argumento VideoFrame, el valor de VideoFrame devuelto tendrá una propiedad SoftwareBitmap que no será nula y una propiedad Direct3DSurface que sí lo será.
  • Si llamas a la sobrecarga de un método GetPreviewFrameAsync que no tenga ningún argumento en un dispositivo que use una superficie de Direct3D para representar el marco internamente, la propiedad Direct3DSurface no será nula y la propiedad SoftwareBitmap sí lo será.
  • Si llamas a la sobrecarga de un método GetPreviewFrameAsync que no tenga ningún argumento en un dispositivo que no use una superficie de Direct3D para representar el marco internamente, la propiedad SoftwareBitmap no será nula y la propiedad Direct3DSurface sí lo será.

La aplicación debe comprobar siempre si hay un valor "null" antes de intentar operar con los objetos devueltos por las propiedades SoftwareBitmap o Direct3DSurface.

Cuando hayas terminado con el marco de vista previa, asegúrate de llamar a su método Close (previsto para Dispose en C#), para liberar los recursos usados por el marco. Igualmente, también puedes usar el patrón using, que elimina automáticamente el objeto.

previewFrame.Dispose();
previewFrame = null;