Фотозахват с расширенным динамическим диапазоном (HDR) и в условиях низкой освещенностиHigh dynamic range (HDR) and low-light photo capture

В этой статье показано, как использовать класс AdvancedPhotoCapture для фотозахвата с расширенным динамическим диапазоном (HDR).This article shows you how to use the AdvancedPhotoCapture class to capture high dynamic range (HDR) photos. Кроме того, этот API дает возможность получить опорный кадр из захвата HDR, прежде чем завершить обработку окончательного изображения.This API also allows you to obtain a reference frame from the HDR capture before the processing of the final image is complete.

Другие статьи, связанные с захватом HDR:Other articles related to HDR capture include:

Примечание

Начиная с Windows 10 версии 1709 поддерживается одновременная запись видео и использование AdvancedPhotoCapture.Starting with Windows 10, version 1709, recording video and using AdvancedPhotoCapture concurrently is supported. Такая функциональность не поддерживается в предыдущих версиях.This is not supported in previous versions. Это изменение означает, что вы можете одновременно подготовить LowLagMediaRecording и AdvancedPhotoCapture.This change means that you can have a prepared LowLagMediaRecording and AdvancedPhotoCapture at the same time. Можно запустить или остановить запись видео между вызовами методов MediaCapture.PrepareAdvancedPhotoCaptureAsync и AdvancedPhotoCapture.FinishAsync.You can start or stop video recording between calls to MediaCapture.PrepareAdvancedPhotoCaptureAsync and AdvancedPhotoCapture.FinishAsync. Вы также можете вызвать AdvancedPhotoCapture.CaptureAsync во время записи видео.You can also call AdvancedPhotoCapture.CaptureAsync while video is recording. Тем не менее при некоторых сценариях использования AdvancedPhotoCapture, например, при записи HDR-фотографий во время ведения видеозаписи, некоторые видеокадры могут быть изменены из-за записи в режиме HDR, а может быть отрицательно воспринято пользователями.However, some AdvancedPhotoCapture scenarios, like capturing an HDR photo while recording video would cause some video frames to be altered by the HDR capture, resulting in a negative user experience. По этой причине во время записи видео AdvancedPhotoControl.SupportedModes возвращает другой список режимов.For this reason, the list of modes returned by the AdvancedPhotoControl.SupportedModes will be different while video is recording. Это значение необходимо проверять сразу же после запуска или остановки видеозаписи, чтобы убедиться, что нужный режим поддерживается на текущем этапе видеозаписи.You should check this value immediately after starting or stopping video recording to ensure that the desired mode is supported in the current video recording state.

Примечание

Начиная с Windows 10 версии 1709, при включении HDR-режима для AdvancedPhotoCapture значение свойства FlashControl.Enabled игнорируется и вспышка никогда не активируется.Starting with Windows 10, version 1709, when the AdvancedPhotoCapture is set to HDR mode, the setting of the FlashControl.Enabled property is ignored and the flash is never fired. В других режимах съемки установленное свойство FlashControl.Enabled переопределяет параметры AdvancedPhotoCapture, поэтому обычные фотографии снимаются со вспышкой.For other capture modes, if the FlashControl.Enabled, it will override the AdvancedPhotoCapture settings and cause a normal photo to be captured with flash. Если в параметре Auto задано значение true, то AdvancedPhotoCapture может использовать или не использовать вспышку, в зависимости от стандартного поведения камеры в условиях текущей сцены фотосъемки.If Auto is set to true, the AdvancedPhotoCapture may or may not use flash, depending on the camera driver's default behavior for the conditions in the current scene. В предыдущих выпусках параметр вспышки AdvancedPhotoCapture всегда переопределял параметр FlashControl.Enabled.On previous releases, the AdvancedPhotoCapture flash setting always overrides the FlashControl.Enabled setting.

Примечание

В этой статье используются понятия и код из статьи Основные принципы фото-, аудио- и видеозахвата с помощью 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. Код в этой статье подразумевает, что ваше приложение уже содержит экземпляр MediaCapture, инициализированный надлежащим образом.The code in this article assumes that your app already has an instance of MediaCapture that has been properly initialized.

Существует универсальной пример Windows, демонстрирующий функциональность класса AdvancedPhotoCapture, с помощью которого можно увидеть API, используемые в контексте. Кроме того, этот класс может служить начальной точкой создания собственного приложения.There is a Universal Windows Sample demonstrating the use of the AdvancedPhotoCapture class that you can use to see the API used in context or as a starting point for your own app. Дополнительные сведения см. в разделе Пример расширенной съемки на камеру.For more information see, Camera Advanced Capture sample.

Пространства имен расширенного фотозахватаAdvanced photo capture namespaces

В примерах кода в этой статье помимо пространств имен, необходимых для основного захвата мультимедиа, используются API в следующих пространствах имен.The code examples in this article use APIs in the following namespaces in addition to the namespaces required for basic media capture.

using Windows.Media.Core;
using Windows.Media.Devices;

Фотозахват HDRHDR photo capture

Определение возможности фотозахвата HDR на текущем устройствеDetermine if HDR photo capture is supported on the current device

Описанный в этой статье способ захвата HDR выполняется с помощью объекта AdvancedPhotoCapture.The HDR capture technique described in this article is performed using the AdvancedPhotoCapture object. Не все устройства поддерживают фотозахват HDR с помощью AdvancedPhotoCapture.Not all devices support HDR capture with AdvancedPhotoCapture. Определите, поддерживает ли этот метод устройство, на котором в настоящее время запущено приложение. Для этого необходимо получить свойство VideoDeviceController объекта MediaCapture, а затем получить свойство AdvancedPhotoControl.Determine if the device on which your app is currently running supports the technique by getting the MediaCapture object's VideoDeviceController and then getting the AdvancedPhotoControl property. Проверьте коллекцию SupportedModes контроллера видеоустройства , чтобы узнать, входит ли в нее режим AdvancedPhotoMode.Hdr. Если входит, то в AdvancedPhotoCapture поддерживается режим записи HDR.Check the video device controller's SupportedModes collection to see if it includes AdvancedPhotoMode.Hdr. If it does, HDR capture using AdvancedPhotoCapture is supported.

bool _hdrSupported;
private void IsHdrPhotoSupported()
{
    _hdrSupported = _mediaCapture.VideoDeviceController.AdvancedPhotoControl.SupportedModes.Contains(Windows.Media.Devices.AdvancedPhotoMode.Hdr);
}

Настройка и подготовка объекта AdvancedPhotoCaptureConfigure and prepare the AdvancedPhotoCapture object

Поскольку необходим доступ к экземпляру AdvancedPhotoCapture из нескольких расположений в пределах вашего кода, нужно объявить переменную-член для удержания объекта.Because you will need to access the AdvancedPhotoCapture instance from multiple places within your code, you should declare a member variable to hold the object.

private AdvancedPhotoCapture _advancedCapture;

В вашем приложении после инициализации объекта MediaCapture создайте объект AdvancedPhotoCaptureSettings и установите режим AdvancedPhotoMode.Hdr. Вызовите метод Configure объекта AdvancedPhotoControl, передав в него созданный объект AdvancedPhotoCaptureSettings.In your app, after you have initialized the MediaCapture object, create an AdvancedPhotoCaptureSettings object and set the mode to AdvancedPhotoMode.Hdr. Call the AdvancedPhotoControl object's Configure method, passing in the AdvancedPhotoCaptureSettings object you created.

Вызовите метод PrepareAdvancedPhotoCaptureAsync объекта MediaCapture, передав объект ImageEncodingProperties с указанием типа кодирования, которое должно использоваться в захвате.Call the MediaCapture object's PrepareAdvancedPhotoCaptureAsync, passing in an ImageEncodingProperties object specifying the type of encoding the capture should use. Класс ImageEncodingProperties предоставляет статические методы для создания кодирования изображений, которые поддерживаются MediaCapture.The ImageEncodingProperties class provides static methods for creating the image encodings that are supported by MediaCapture.

PrepareAdvancedPhotoCaptureAsync возвращает объект AdvancedPhotoCapture, который будет использоваться для инициализации фотозахвата.PrepareAdvancedPhotoCaptureAsync returns the AdvancedPhotoCapture object you will use to initiate photo capture. Вы можете использовать этот объект, чтобы зарегистрировать обработчики событий для OptionalReferencePhotoCaptured и AllPhotosCaptured, которые описываются далее в этой статье.You can use this object to register handlers for the OptionalReferencePhotoCaptured and AllPhotosCaptured which are discussed later in this article.

if (_hdrSupported == false) return;

// Choose HDR mode
var settings = new AdvancedPhotoCaptureSettings { Mode = AdvancedPhotoMode.Hdr };

// Configure the mode
_mediaCapture.VideoDeviceController.AdvancedPhotoControl.Configure(settings);

// Prepare for an advanced capture
_advancedCapture = 
    await _mediaCapture.PrepareAdvancedPhotoCaptureAsync(ImageEncodingProperties.CreateUncompressed(MediaPixelFormat.Nv12));

// Register for events published by the AdvancedCapture
_advancedCapture.AllPhotosCaptured += AdvancedCapture_AllPhotosCaptured;
_advancedCapture.OptionalReferencePhotoCaptured += AdvancedCapture_OptionalReferencePhotoCaptured;

Захват фотографий с технологией HDRCapture an HDR photo

Чтобы захватить фотографию с расширенным динамическим диапазоном (HDR), вызовите метод CaptureAsync объекта AdvancedPhotoCapture.Capture an HDR photo by calling the AdvancedPhotoCapture object's CaptureAsync method. Этот метод возвращает объект AdvancedCapturedPhoto, предоставляющий созданную фотографию в свойстве Frame.This method returns an AdvancedCapturedPhoto object that provides the captured photo in its Frame property.

try
{

    // Start capture, and pass the context object
    AdvancedCapturedPhoto advancedCapturedPhoto = await _advancedCapture.CaptureAsync();

    using (var frame = advancedCapturedPhoto.Frame)
    {
        // Read the current orientation of the camera and the capture time
        var photoOrientation = CameraRotationHelper.ConvertSimpleOrientationToPhotoOrientation(
            _rotationHelper.GetCameraCaptureOrientation());
        var fileName = String.Format("SimplePhoto_{0}_HDR.jpg", DateTime.Now.ToString("HHmmss"));
        await SaveCapturedFrameAsync(frame, fileName, photoOrientation);
    }
}
catch (Exception ex)
{
    Debug.WriteLine("Exception when taking an HDR photo: {0}", ex.ToString());
}

Большинство приложений фотографии кодируют поворот сделанного фото в файле изображения, чтобы он правильно отображался в других приложениях и на других устройствах.Most photography apps will want to encode a captured photo's rotation into the image file so that it can be displayed correctly by other apps and devices. В этом примере показано использование вспомогательного класса CameraRotationHelper для расчета правильной ориентации файла.This example shows the use of the helper class CameraRotationHelper to calculate the proper orientation for the file. Этот класс более подробно описан в статье Обработка ориентации устройства с помощью MediaCapture.This class is described and listed in full in the article Handle device orientation with MediaCapture.

Вспомогательный метод SaveCapturedFrameAsync, который сохраняет изображение на диск, рассматривается далее в этой статье.The SaveCapturedFrameAsync helper method, which saves the image to disk, is discussed later in this article.

Получение дополнительного опорного кадраGet optional reference frame

При использовании технологии HDR захватывается несколько кадров. После захвата всех кадров из них составляется одно изображение.The HDR process captures multiple frames and then composites them into a single image after all of the frames have been captured. Вы можете получить доступ к кадру после его захвата, но до завершения обработки HDR, обработав событие OptionalReferencePhotoCaptured.You can get access to a frame after it is captured but before the entire HDR process is complete by handling the OptionalReferencePhotoCaptured event. Если вас интересует только конечный результат фотографии с расширенным динамическим диапазоном (HDR), этого делать не нужно.You don't need to do this if you are only interested in the final HDR photo result.

Важно!

OptionalReferencePhotoCaptured не вызывается на устройствах, которые поддерживают HDR-оборудование, а потому не создают опорные кадры.OptionalReferencePhotoCaptured is not raised on devices that support hardware HDR and therefore do not generate reference frames. В приложении должны предусматриваться случаи, при которых это событие не возникает.Your app should handle the case where this event is not raised.

Поскольку опорный кадр поступает из контекста вызова CaptureAsync, предусмотрен механизм для передачи контекстной информации обработчику OptionalReferencePhotoCaptured.Because the reference frame arrives out of context of the call to CaptureAsync, a mechanism is provided to pass context information to the OptionalReferencePhotoCaptured handler. Сначала нужно вызвать объект, который будет содержать контекстные данные.First you should call an object that will contain your context information. При этом имя и содержимое этого объекта зависит только от вас.The name and contents of this object is up to you. В этом примере определяется объект, который содержит члены для отслеживания имени файла и ориентации камеры при захвате.This example defines an object that has members to track the file name and camera orientation of the capture.

public class MyAdvancedCaptureContextObject
{
    public string CaptureFileName;
    public PhotoOrientation CaptureOrientation;
}

Создайте экземпляр объекта контекста, добавьте его члены, а затем передайте его в перегрузку CaptureAsync, где объект принимается в качестве параметра.Create a new instance of your context object, populate its members, and then pass it into the overload of CaptureAsync that accepts an object as a parameter.

// Read the current orientation of the camera and the capture time
var photoOrientation = CameraRotationHelper.ConvertSimpleOrientationToPhotoOrientation(
        _rotationHelper.GetCameraCaptureOrientation());
var fileName = String.Format("SimplePhoto_{0}_HDR.jpg", DateTime.Now.ToString("HHmmss"));

// Create a context object, to identify the capture in the OptionalReferencePhotoCaptured event
var context = new MyAdvancedCaptureContextObject()
{
    CaptureFileName = fileName,
    CaptureOrientation = photoOrientation
};

// Start capture, and pass the context object
AdvancedCapturedPhoto advancedCapturedPhoto = await _advancedCapture.CaptureAsync(context);

В обработчике событий OptionalReferencePhotoCaptured приведите свойство Context объекта OptionalReferencePhotoCapturedEventArgs к классу объектов контекста.In the OptionalReferencePhotoCaptured event handler, cast the Context property of the OptionalReferencePhotoCapturedEventArgs object to your context object class. В этом примере изменяется имя файла для разделения изображения опорного кадра и окончательного изображения с расширенным динамическим диапазоном (HDR), а затем вызывается вспомогательный метод SaveCapturedFrameAsync, чтобы сохранить изображение.This example modifies the file name to distinguish the reference frame image from the final HDR image and then calls the SaveCapturedFrameAsync helper method to save the image.

private async void AdvancedCapture_OptionalReferencePhotoCaptured(AdvancedPhotoCapture sender, OptionalReferencePhotoCapturedEventArgs args)
{
    // Retrieve the context (i.e. what capture does this belong to?)
    var context = args.Context as MyAdvancedCaptureContextObject;

    // Remove "_HDR" from the name of the capture to create the name of the reference
    var referenceName = context.CaptureFileName.Replace("_HDR", "");

    using (var frame = args.Frame)
    {
        await SaveCapturedFrameAsync(frame, referenceName, context.CaptureOrientation);
    }
}

Получение уведомления после захвата всех кадровReceive a notification when all frames have been captured

Фотозахват с технологией HDR предполагает два шага.The HDR photo capture has two steps. Сначала захватывается несколько кадров, а затем кадры обрабатываются и создается окончательное HDR-изображение.First, multiple frames are captured, and then the frames are processed into the final HDR image. Инициировать другой захват во время захвата исходных кадров HDR нельзя. Однако это можно сделать после захвата всех кадров, но до завершающей обработки HDR.You can't initiate another capture while the source HDR frames are still being captured, but you can initiate a capture after all of the frames have been captured but before the HDR post-processing is complete. Событие AllPhotosCaptured возникает после завершения захвата HDR, уведомляя вас о том, что вы можете инициировать другой захват.The AllPhotosCaptured event is raised when the HDR captures are complete, letting you know that you can initiate another capture. Обычный сценарий — отключить кнопку захвата пользовательского интерфейса в начале захвата с HDR, а затем снова включить ее при вызове AllPhotosCaptured.A typical scenario is to disable your UI's capture button when HDR capture begins and then reenable it when AllPhotosCaptured is raised.

private void AdvancedCapture_AllPhotosCaptured(AdvancedPhotoCapture sender, object args)
{
    // Update UI to enable capture button
}

Удаление объекта AdvancedPhotoCaptureClean up the AdvancedPhotoCapture object

Когда приложение завершит захват, прежде чем ликвидировать объект MediaCapture, необходимо завершить работу объекта AdvancedPhotoCapture. Для этого вызовите FinishAsync и установите для переменной-члена значение Null.When your app is done capturing, before disposing of the MediaCapture object, you should shut down the AdvancedPhotoCapture object by calling FinishAsync and setting your member variable to null.

await _advancedCapture.FinishAsync();
_advancedCapture = null;

Фотозахват при слабом освещенииLow-light photo capture

Начиная c Windows 10 (версия 1607) класс AdvancedPhotoCapture можно использовать для съемки фото с применением встроенного алгоритма, который повышает качество фото, сделанных в условиях низкой освещенности.Starting with Windows 10, version 1607, AdvancedPhotoCapture can be used to capture photos using a built-in algorithm that enhances the quality of photos captured in low-light settings. При использовании функции съемки при низком освещении, предоставляемой классом AdvancedPhotoCapture, система оценивает текущую сцену и при необходимости применяет алгоритм, компенсирующий условия низкой освещенности.When you use the low-light feature of the AdvancedPhotoCapture class, the system will evaluate the current scene and, if needed, apply an algorithm to compensate for low-light conditions. Если система определяет, что этот алгоритм не нужен, выполняется обычный захват.If the system determines that the algorithm is not needed, a regular capture is performed instead.

Прежде чем использовать фотозахват в условиях низкой освещенности, определите, поддерживает ли этот метод устройство, на котором в настоящее время запущено приложение. Для этого необходимо получить свойство VideoDeviceController объекта MediaCapture, а затем получить свойство AdvancedPhotoControl.Before using low-light photo capture, determine if the device on which your app is currently running supports the technique by getting the MediaCapture object's VideoDeviceController and then getting the AdvancedPhotoControl property. Просмотрите коллекцию контроллера видеоустройств SupportedModes, чтобы узнать, включает ли она AdvancedPhotoMode.LowLight.Check the video device controller's SupportedModes collection to see if it includes AdvancedPhotoMode.LowLight. Если да, то захват в условиях низкого освещения с использованием AdvancedPhotoCapture поддерживается.If it does, low-light capture using AdvancedPhotoCapture is supported.

bool _lowLightSupported;
_lowLightSupported = 
_mediaCapture.VideoDeviceController.AdvancedPhotoControl.SupportedModes.Contains(Windows.Media.Devices.AdvancedPhotoMode.LowLight);

Затем объявите переменную-член для хранения объекта AdvancedPhotoCapture.Next, declare a member variable to store the AdvancedPhotoCapture object.

private AdvancedPhotoCapture _advancedCapture;

После того как вы инициализировали объект MediaCapture, создайте в своем приложении объект AdvancedPhotoCaptureSettings и установите режим AdvancedPhotoMode.LowLight.In your app, after you have initialized the MediaCapture object, create an AdvancedPhotoCaptureSettings object and set the mode to AdvancedPhotoMode.LowLight. Вызовите метод Configure объекта AdvancedPhotoControl, передав созданный объект AdvancedPhotoCaptureSettings.Call the AdvancedPhotoControl object's Configure method, passing in the AdvancedPhotoCaptureSettings object you created.

Вызовите метод PrepareAdvancedPhotoCaptureAsync объекта MediaCapture, передав объект ImageEncodingProperties с указанием типа кодирования, которое должно использоваться в захвате.Call the MediaCapture object's PrepareAdvancedPhotoCaptureAsync, passing in an ImageEncodingProperties object specifying the type of encoding the capture should use.

if (_lowLightSupported == false) return;

// Choose LowLight mode
var settings = new AdvancedPhotoCaptureSettings { Mode = AdvancedPhotoMode.LowLight };
_mediaCapture.VideoDeviceController.AdvancedPhotoControl.Configure(settings);

// Prepare for an advanced capture
_advancedCapture = 
    await _mediaCapture.PrepareAdvancedPhotoCaptureAsync(ImageEncodingProperties.CreateUncompressed(MediaPixelFormat.Nv12));

Чтобы сделать фото, вызовите метод CaptureAsync.To capture a photo, call CaptureAsync.

AdvancedCapturedPhoto advancedCapturedPhoto = await _advancedCapture.CaptureAsync();
var photoOrientation = ConvertOrientationToPhotoOrientation(GetCameraOrientation());
var fileName = String.Format("SimplePhoto_{0}_LowLight.jpg", DateTime.Now.ToString("HHmmss"));
await SaveCapturedFrameAsync(advancedCapturedPhoto.Frame, fileName, photoOrientation);

Как и в примере HDR выше, здесь используется вспомогательный класс CameraRotationHelper, чтобы определить значение поворота, которое необходимо добавить в код изображения, чтобы оно правильно отображалось в других приложениях и на других устройствах.Like the HDR example above, this example uses a helper class called CameraRotationHelper to determine the rotation value that should be encoded into the image so that it can be displayed properly by other apps and devices. Этот класс более подробно описан в статье Обработка ориентации устройства с помощью MediaCapture.This class is described and listed in full in the article Handle device orientation with MediaCapture.

Вспомогательный метод SaveCapturedFrameAsync, который сохраняет изображение на диск, рассматривается далее в этой статье.The SaveCapturedFrameAsync helper method, which saves the image to disk, is discussed later in this article.

Можно сделать несколько фото в условиях низкого освещения, не изменяя настройки объекта AdvancedPhotoCapture, однако по завершении фотозахвата необходимо вызвать метод FinishAsync, чтобы удалить объект и связанные ресурсы.You can capture multiple low-light photos without reconfiguring the AdvancedPhotoCapture object, but when you are done capturing, you should call FinishAsync to clean up the object and associated resources.

await _advancedCapture.FinishAsync();
_advancedCapture = null;

Работа с объектами AdvancedCapturedPhotoWorking with AdvancedCapturedPhoto objects

AdvancedPhotoCapture.CaptureAsync возвращает объект AdvancedCapturedPhoto, представляющий сделанное фото.AdvancedPhotoCapture.CaptureAsync returns an AdvancedCapturedPhoto object representing the captured photo. Этот объект предоставляет свойство Frame, которое возвращает объект CapturedFrame, представляющий изображение.This object exposes the Frame property which returns a CapturedFrame object representing the image. Событие OptionalReferencePhotoCaptured также предоставляет объект CapturedFrame в аргументах события.The OptionalReferencePhotoCaptured event also provides a CapturedFrame object in its event args. Получив объект этого типа, с ним можно выполнить несколько действий, включая создание SoftwareBitmap или сохранение изображения в файл.After you get an object of this type, there are a number of things you can do with it, including creating a SoftwareBitmap or saving the image to a file.

Получение объекта SoftwareBitmap из CapturedFrameGet a SoftwareBitmap from a CapturedFrame

Чтобы получить SoftwareBitmap из объекта CapturedFrame, нужно всего лишь получить доступ к свойству SoftwareBitmap объекта.It's trivial to get a SoftwareBitmap from a CapturedFrame object by simply accessing the SoftwareBitmap property of the object. Однако большинство форматов кодирования не поддерживают свойство SoftwareBitmap с AdvancedPhotoCapture, поэтому прежде необходимо проверить и убедиться, что это свойство не равно null.However, most encoding formats do not support SoftwareBitmap with AdvancedPhotoCapture, so you should check and make sure the property is not null before using it.

SoftwareBitmap bitmap;
if (advancedCapturedPhoto.Frame.SoftwareBitmap != null)
{
    bitmap = advancedCapturedPhoto.Frame.SoftwareBitmap;
}

Единственный формат кодирования, поддерживающий свойство SoftwareBitmap для AdvancedPhotoCapture, в этом выпуске — это несжатый NV12.In the current release, the only encoding format that supports SoftwareBitmap for AdvancedPhotoCapture is uncompressed NV12. Поэтому если требуется использовать эту функцию, необходимо задать эту кодировку при вызове метода PrepareAdvancedPhotoCaptureAsync.So, if you want to use this feature, you must specify that encoding when you call PrepareAdvancedPhotoCaptureAsync.

_advancedCapture =
    await _mediaCapture.PrepareAdvancedPhotoCaptureAsync(ImageEncodingProperties.CreateUncompressed(MediaPixelFormat.Nv12));

Конечно, всегда можно сохранить изображение в файл, а затем загрузить файл в SoftwareBitmap отдельным действием.Of course, you can always save the image to a file and then load the file into a SoftwareBitmap in a separate step. Дополнительные сведения о работе с SoftwareBitmap см. в разделе Создание, редактирование и сохранение растровых изображений.For more information about working with SoftwareBitmap, see Create, edit, and save bitmap images.

Сохранение CapturedFrame в файлSave a CapturedFrame to a file

Класс CapturedFrame реализует интерфейс IInputStream, чтобы его можно было использовать в качестве ввода в BitmapDecoder, после чего BitmapEncoder можно использовать для записи данных изображения на диск.The CapturedFrame class implements the IInputStream interface, so it can be used as the input to a BitmapDecoder, and then a BitmapEncoder can be used to write the image data to disk.

В следующем примере создается новая папка в библиотеке изображений пользователя и в этой папке создается файл.In the following example, a new folder in the user's pictures library is created and a file is created within this folder. Обратите внимание, что для получения доступа к этому каталогу файл манифеста вашего приложения должен включать функцию Библиотека изображений.Note that your app will need to include the Pictures Library capability in your app manifest file in order to access this directory. Затем поток файлов открывается в заданном файле.A file stream is then opened to the specified file. После этого вызывается метод BitmapDecoder.CreateAsync для создания декодера из CapturedFrame.Next, the BitmapDecoder.CreateAsync is called to create the decoder from the CapturedFrame. Затем CreateForTranscodingAsync создает кодировщик из потока файлов и декодера.Then CreateForTranscodingAsync creates an encoder from the file stream and the decoder.

Дальнейшие шаги включают кодирование ориентации фото и включение этого кода в файл изображения с помощью BitmapProperties кодировщика.The next steps encode the orientation of the photo into the image file by using the BitmapProperties of the encoder. Дополнительные сведения об ориентации при создании изображений см. в разделе Обработка ориентации устройства с использованием MediaCapture.For more information about handling orientation when capturing images, see Handle device orientation with MediaCapture.

Наконец, изображение записывается в файл вызовом метода FlushAsync.Finally, the image is written to the file with a call to FlushAsync.

private static async Task<StorageFile> SaveCapturedFrameAsync(CapturedFrame frame, string fileName, PhotoOrientation photoOrientation)
{
    var folder = await KnownFolders.PicturesLibrary.CreateFolderAsync("MyApp", CreationCollisionOption.OpenIfExists);
    var file = await folder.CreateFileAsync(fileName, CreationCollisionOption.GenerateUniqueName);

    using (var inputStream = frame)
    {
        using (var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite))
        {
            var decoder = await BitmapDecoder.CreateAsync(inputStream);
            var encoder = await BitmapEncoder.CreateForTranscodingAsync(fileStream, decoder);
            var properties = new BitmapPropertySet {
                { "System.Photo.Orientation", new BitmapTypedValue(photoOrientation, PropertyType.UInt16) } };
            await encoder.BitmapProperties.SetPropertiesAsync(properties);
            await encoder.FlushAsync();
        }
    }
    return file;
}