Получение кадра предварительного просмотра

В этом разделе объясняется, как получить один кадр предварительного просмотра из потока предварительного просмотра захвата мультимедийного содержимого.

Примечание

В этой статье используются понятия и код из статьи Основные принципы фото-, аудио- и видеозахвата с помощью MediaCapture, в которой описаны этапы реализации основных принципов фото- и видеозахвата. Мы рекомендуем ознакомиться с базовым шаблоном захвата мультимедиа в этой статье, прежде чем перейти к более сложным сценариям захвата. Код в этой статье рассчитан на то, что ваше приложение уже содержит экземпляр MediaCapture, который был инициализирован надлежащим образом, и что у вас есть объект CaptureElement с активным видеопотоком предварительного просмотра.

Помимо пространства имен, необходимого для основного захвата мультимедиа, для захвата кадра предварительного просмотра требуется следующее пространство имен.

using Windows.Media;

При запросе кадра предварительного просмотра вы можете указать формат, в котором требуется получить кадр. Для этого создайте объект VideoFrame в соответствующем формате. В этом примере будет создан видеокадр с тем же разрешением, что и у потока предварительного просмотра. В ходе него вызывается метод VideoDeviceController.GetMediaStreamProperties и указывается тип MediaStreamType.VideoPreview для запроса свойств для потока предварительного просмотра. Ширина и высота потока предварительного просмотра используются для создания видеокадра.

// 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, чтобы получить доступ к потоку предварительного просмотра. В качестве параметров задайте видеокадр, созданный на последнем шаге, чтобы указать формат возвращенного кадра.

VideoFrame previewFrame = await _mediaCapture.GetPreviewFrameAsync(videoFrame);

Получите кадр предварительного просмотра в представлении SoftwareBitmap, обратившись к свойству SoftwareBitmap объекта VideoFrame. Сведения о сохранении, загрузке и изменении точечных рисунков программного обеспечения см. в разделе Обработка изображений.

SoftwareBitmap previewBitmap = previewFrame.SoftwareBitmap;

Вы также можете получить доступ к кадру предварительного просмотра в представлении IDirect3DSurface, чтобы использовать изображение с API Direct3D.

var previewSurface = previewFrame.Direct3DSurface;

Важно!

Свойство SoftwareBitmap или свойство Direct3DSurface возвращенного объекта VideoFrame может иметь нулевое значение в зависимости от того, как был вызван метод GetPreviewFrameAsync, а также в зависимости от устройства, на котором выполняется приложение.

  • Если вызвать перегрузку метода GetPreviewFrameAsync, которая принимает аргумент VideoFrame, то возвращенный объект VideoFrame будет иметь значение SoftwareBitmap, отличное от нулевого, а свойство Direct3DSurface будет иметь нулевое значение.
  • Если вызвать перегрузку GetPreviewFrameAsync, которое не располагает аргументами на устройстве, использующем поверхность Direct3D для представления кадра внутри себя, свойство Direct3DSurface будет иметь значение, отличное от нулевого, а свойство SoftwareBitmap будет иметь нулевое значение.
  • Если вызвать перегрузку GetPreviewFrameAsync, которое не располагает аргументами на устройстве, не использующем поверхность Direct3D для представления кадра внутри себя, свойство SoftwareBitmap будет иметь значение, отличное от нулевого, а свойство Direct3DSurface будет иметь нулевое значение.

Ваше приложение должно всегда проверять нулевое значение перед попыткой работы с объектами, возвращенными свойством SoftwareBitmap или Direct3DSurface.

Поработав с кадром предварительного просмотра, не забудьте вызвать его метод Close (сопоставляемый с Dispose в C#), чтобы освободить ресурсы, используемые кадром. Можно также использовать шаблон using, который автоматически ликвидирует объект.

previewFrame.Dispose();
previewFrame = null;