Captura de foto de pouca luz e HDR (High Dynamic Range)High dynamic range (HDR) and low-light photo capture

Este artigo mostra como usar a classe AdvancedPhotoCapture para capturar fotos HDR (High Dynamic Range).This article shows you how to use the AdvancedPhotoCapture class to capture high dynamic range (HDR) photos. Essa API também permite que você obtenha um quadro de referência da captura HDR antes que o processamento da imagem final seja concluído.This API also allows you to obtain a reference frame from the HDR capture before the processing of the final image is complete.

Outros artigos relacionados à captura HDR incluem:Other articles related to HDR capture include:

Observação

A partir do Windows 10, versão 1709, há suporte para a gravação de vídeo e o uso de AdvancedPhotoCapture simultaneamente.Starting with Windows 10, version 1709, recording video and using AdvancedPhotoCapture concurrently is supported. Isso não é possível em versões anteriores.This is not supported in previous versions. Essa alteração significa que você pode ter uma LowLagMediaRecording preparada e uma AdvancedPhotoCapture ao mesmo tempo.This change means that you can have a prepared LowLagMediaRecording and AdvancedPhotoCapture at the same time. Você pode iniciar ou parar a gravação de vídeo entre chamadas para MediaCapture.PrepareAdvancedPhotoCaptureAsync e AdvancedPhotoCapture.FinishAsync.You can start or stop video recording between calls to MediaCapture.PrepareAdvancedPhotoCaptureAsync and AdvancedPhotoCapture.FinishAsync. Você também pode chamar AdvancedPhotoCapture.CaptureAsync enquanto o vídeo é gravado.You can also call AdvancedPhotoCapture.CaptureAsync while video is recording. No entanto, alguns cenários de AdvancedPhotoCapture, como capturar uma foto HDR, enquanto a gravação de vídeo resulta na alteração de alguns quadros de vídeo pela captura de HDR, resultando em uma experiência de usuário negativa.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. Por esse motivo, a lista de modos retornada pelo AdvancedPhotoControl.SupportedModes será diferente enquanto o vídeo é gravado.For this reason, the list of modes returned by the AdvancedPhotoControl.SupportedModes will be different while video is recording. Você deve verificar esse valor imediatamente depois de iniciar ou parar a gravação de vídeo para garantir que o modo desejado seja suportado no estado de gravação de vídeo atual.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.

Observação

A partir do Windows 10, versão 1709, quando a AdvancedPhotoCapture é definida como o modo HDR, a configuração da propriedade FlashControl.Enabled é ignorada e o flash nunca é acionado.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. Para outros modos de captura, se FlashControl.Enabled, isso substitui as configurações de AdvancedPhotoCapture e resulta na captura de uma foto normal com flash.For other capture modes, if the FlashControl.Enabled, it will override the AdvancedPhotoCapture settings and cause a normal photo to be captured with flash. Se Auto estiver configurado como true, a AdvancedPhotoCapture pode ou não usar o flash, dependendo do comportamento padrão do driver da câmera para as condições na cena atual.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. Em versões anteriores, a configuração de flash de AdvancedPhotoCapture sempre substitui a configuração de FlashControl.Enabled.On previous releases, the AdvancedPhotoCapture flash setting always overrides the FlashControl.Enabled setting.

Observação

Este artigo se baseia em conceitos e códigos discutidos em Captura básica de fotos, áudio e vídeo com o MediaCapture, que descreve as etapas para implementar uma captura básica de fotos e vídeos.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. Recomendamos que você se familiarize com o padrão de captura de mídia básica neste artigo antes de passar para cenários de captura mais avançados.We recommend that you familiarize yourself with the basic media capture pattern in that article before moving on to more advanced capture scenarios. O código neste artigo presume que seu aplicativo já tenha uma instância de MediaCapture inicializada corretamente.The code in this article assumes that your app already has an instance of MediaCapture that has been properly initialized.

Há um exemplo Universal do Windows que demonstra o uso da classe AdvancedPhotoCapture que você pode usar para ver a API usada no contexto ou como ponto de partida para seu próprio aplicativo.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. Para obter mais informações, consulte o exemplo de captura avançada com câmera.For more information see, Camera Advanced Capture sample.

Namespaces de captura de foto avançadaAdvanced photo capture namespaces

Os exemplos de código neste artigo usam APIs nos namespaces a seguir, além dos namespaces necessários para captura de mídia básica.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;

Captura de foto HDRHDR photo capture

Determinar se a captura de fotos HDR é aceita no dispositivo atualDetermine if HDR photo capture is supported on the current device

A técnica de captura HDR descrita neste artigo é executada usando o objeto AdvancedPhotoCapture.The HDR capture technique described in this article is performed using the AdvancedPhotoCapture object. Nem todos os dispositivos oferecem suporte à AdvancedPhotoCapture.Not all devices support HDR capture with AdvancedPhotoCapture. Determine se o dispositivo em que seu aplicativo está sendo executado oferece suporte à técnica obtendo o VideoDeviceController do objeto MediaCapture e depois obtendo a propriedade 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. Verifique a coleção SupportedModes do controlador de dispositivo de vídeo para verificar se inclui AdvancedPhotoMode.Hdr. Caso inclua, a capture HDR usando AdvancedPhotoCapture é suportada.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);
}

Configurar e preparar o objeto AdvancedPhotoCaptureConfigure and prepare the AdvancedPhotoCapture object

Como você precisará acessar a instância de AdvancedPhotoCapture em vários locais em seu código, será necessário declarar uma variável de membro para armazenar o objeto.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;

No aplicativo, depois de inicializar o objeto MediaCapture, crie um objeto AdvancedPhotoCaptureSettings e defina o modo como AdvancedPhotoMode.Hdr. Faça uma chamada com o objeto AdvancedPhotoControl usando o método Configure, passando o objeto AdvancedPhotoCaptureSettings criado.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.

Chame o PrepareAdvancedPhotoCaptureAsync do objeto MediaCapture passando um objeto ImageEncodingProperties especificando o tipo de codificação que a captura deve usar.Call the MediaCapture object's PrepareAdvancedPhotoCaptureAsync, passing in an ImageEncodingProperties object specifying the type of encoding the capture should use. A classe ImageEncodingProperties fornece métodos estáticos para criar as codificações de imagem que são suportadas pelo MediaCapture.The ImageEncodingProperties class provides static methods for creating the image encodings that are supported by MediaCapture.

PrepareAdvancedPhotoCaptureAsync retorna o objeto AdvancedPhotoCapture que você usará para iniciar a captura de foto.PrepareAdvancedPhotoCaptureAsync returns the AdvancedPhotoCapture object you will use to initiate photo capture. Use esse objeto para registrar manipuladores para OptionalReferencePhotoCaptured e AllPhotosCaptured que são discutidos posteriormente neste artigo.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;

Capturar uma foto HDRCapture an HDR photo

Capture uma foto HDR, chame o método CaptureAsync do objeto AdvancedPhotoCapture.Capture an HDR photo by calling the AdvancedPhotoCapture object's CaptureAsync method. Esse método retorna um objeto AdvancedCapturedPhoto que fornece a foto capturada em sua propriedade 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());
}

A maioria dos aplicativos de fotografia vai querer codificar a rotação da foto capturada no arquivo de imagem para que ela possa ser exibida corretamente por outros aplicativos e dispositivos.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. Este exemplo mostra o uso da classe auxiliar CameraRotationHelper para calcular a orientação adequada para o arquivo.This example shows the use of the helper class CameraRotationHelper to calculate the proper orientation for the file. Essa classe é descrita e listada na íntegra no artigo Tratar a orientação do dispositivo com MediaCapture.This class is described and listed in full in the article Handle device orientation with MediaCapture.

O método auxiliar SaveCapturedFrameAsync, que salva a imagem em disco, será abordado posteriormente neste artigo.The SaveCapturedFrameAsync helper method, which saves the image to disk, is discussed later in this article.

Obter o quadro de referência opcionalGet optional reference frame

O processo HDR captura vários quadros e, em seguida, compõe esses quadros em uma única imagem depois de todos os quadros serem capturados.The HDR process captures multiple frames and then composites them into a single image after all of the frames have been captured. Você pode acessar um quadro após sua captura, mas antes da conclusão do processo de HDR manipulando o evento 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. Você não precisará fazer isso se só estiver interessado no resultado final de fotos HDR.You don't need to do this if you are only interested in the final HDR photo result.

Importante

OptionalReferencePhotoCaptured não é gerado nos dispositivos com suporte para HDR de hardware e, portanto, não gera quadros de referência.OptionalReferencePhotoCaptured is not raised on devices that support hardware HDR and therefore do not generate reference frames. Seu aplicativo deve manipular o caso em que esse evento não for gerado.Your app should handle the case where this event is not raised.

Como o quadro de referência é decorrente do contexto da chamada para CaptureAsync, um mecanismo é fornecido para passar informações de contexto ao manipulador 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. Primeiro você deve chamar um objeto que contenha as informações de contexto.First you should call an object that will contain your context information. O nome e o conteúdo desse objeto dependem de você.The name and contents of this object is up to you. Este exemplo define um objeto que tem membros para controlar o nome de arquivo e a orientação de câmera da captura.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;
}

Crie uma nova instância do seu objeto de contexto, popule seus membros e passe-os para a sobrecarga de CaptureAsync que aceita um objeto como parâmetro.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);

No manipulador de eventos OptionalReferencePhotoCaptured, converta a propriedade Context do objeto OptionalReferencePhotoCapturedEventArgs na sua classe de objeto de contexto.In the OptionalReferencePhotoCaptured event handler, cast the Context property of the OptionalReferencePhotoCapturedEventArgs object to your context object class. Este exemplo modifica o nome do arquivo para distinguir a imagem do quadro de referência da imagem HDR final e depois chama o método auxiliar SaveCapturedFrameAsync para salvar a imagem.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);
    }
}

Receber uma notificação quando todos os quadros foram capturadosReceive a notification when all frames have been captured

A captura de fotos HDR tem duas etapas.The HDR photo capture has two steps. Primeiro, vários quadros são capturados e, em seguida, os quadros são processados na imagem HDR final.First, multiple frames are captured, and then the frames are processed into the final HDR image. Você não pode iniciar outra captura quando os quadros HDR de origem ainda estiverem sendo capturados, mas pode iniciar uma captura depois que todos os quadros forem capturados, mas antes da conclusão do pós-processamento de 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. O evento AllPhotosCaptured é gerado quando as capturas HDR são concluídas, permitindo que você saiba que pode iniciar outra captura.The AllPhotosCaptured event is raised when the HDR captures are complete, letting you know that you can initiate another capture. Um cenário típico é desabilitar o botão de captura da sua interface do usuário quando a captura HDR começar e habilitá-la novamente quando AllPhotosCaptured for gerado.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
}

Limpar o objeto AdvancedPhotoCaptureClean up the AdvancedPhotoCapture object

Quando seu aplicativo terminar de capturar, antes do descarte do objeto MediaCapture, você deve desligar o objeto AdvancedPhotoCapture chamando FinishAsync e definindo sua variável de membro como nula.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;

Captura de fotos com pouca luzLow-light photo capture

A partir do Windows 10, versão 1607, o AdvancedPhotoCapture pode ser usado para capturar fotos usando um algoritmo interno que melhora a qualidade das fotos capturadas nas configurações de pouca luz.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. Quando você usar o recurso de pouca luz da classe AdvancedPhotoCapture, o sistema avaliará a cena atual e, se necessário, aplicará um algoritmo para compensar as condições de pouca luz.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. Se o sistema determinar que o algoritmo não é necessário, uma captura normal será realizada.If the system determines that the algorithm is not needed, a regular capture is performed instead.

Antes de usar a captura com pouca luz, determine se o dispositivo em que seu aplicativo está sendo executado oferece suporte à técnica obtendo o VideoDeviceController do objeto MediaCapture e depois obtendo a propriedade 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. Verifique a coleção de SupportedModes do controlador do dispositivo de vídeo para ver se ele inclui AdvancedPhotoMode.LowLight.Check the video device controller's SupportedModes collection to see if it includes AdvancedPhotoMode.LowLight. Se incluir, há suporte para a captura com pouca luz usando AdvancedPhotoCapture.If it does, low-light capture using AdvancedPhotoCapture is supported.

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

Em seguida, declare uma variável membro para armazenar o objeto AdvancedPhotoCapture.Next, declare a member variable to store the AdvancedPhotoCapture object.

private AdvancedPhotoCapture _advancedCapture;

Em seu aplicativo, após a inicialização do objeto MediaCapture, crie um objeto AdvancedPhotoCaptureSettings e defina o modo como AdvancedPhotoMode.LowLight.In your app, after you have initialized the MediaCapture object, create an AdvancedPhotoCaptureSettings object and set the mode to AdvancedPhotoMode.LowLight. Chame o método Configure do objeto AdvancedPhotoControl passando o objeto AdvancedPhotoCaptureSettings que você criou.Call the AdvancedPhotoControl object's Configure method, passing in the AdvancedPhotoCaptureSettings object you created.

Chame o PrepareAdvancedPhotoCaptureAsync do objeto MediaCapture passando um objeto ImageEncodingProperties especificando o tipo de codificação que a captura deve usar.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));

Para capturar uma foto, chame 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);

Como o exemplo de HDR acima, este exemplo usa uma classe auxiliar chamada CameraRotationHelper para determinar o valor de rotação que deve ser codificado na imagem para que ela possa ser exibida corretamente por outros aplicativos e dispositivos.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. Essa classe é descrita e listada na íntegra no artigo Tratar a orientação do dispositivo com MediaCapture.This class is described and listed in full in the article Handle device orientation with MediaCapture.

O método auxiliar SaveCapturedFrameAsync, que salva a imagem em disco, será abordado posteriormente neste artigo.The SaveCapturedFrameAsync helper method, which saves the image to disk, is discussed later in this article.

Você pode capturar várias fotos com pouca luz sem precisar reconfigurar o objeto AdvancedPhotoCapture, mas quando terminar a captura, deverá chamar FinishAsync para limpar o objeto e os recursos associados.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;

Trabalhando com objetos AdvancedCapturedPhotoWorking with AdvancedCapturedPhoto objects

AdvancedPhotoCapture.CaptureAsync retorna um objeto AdvancedCapturedPhoto que representa a foto capturada.AdvancedPhotoCapture.CaptureAsync returns an AdvancedCapturedPhoto object representing the captured photo. Esse objeto expõe a propriedade Frame que retorna um objeto CapturedFrame que representa a imagem.This object exposes the Frame property which returns a CapturedFrame object representing the image. O evento OptionalReferencePhotoCaptured também fornece um objeto CapturedFrame em seus argumentos de evento.The OptionalReferencePhotoCaptured event also provides a CapturedFrame object in its event args. Depois de obter um objeto desse tipo, há uma série de coisas que você poderá fazer com ele, inclusive criar um SoftwareBitmap ou salvar a imagem em um arquivo.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.

Obter um SoftwareBitmap de um CapturedFrameGet a SoftwareBitmap from a CapturedFrame

É muito simples obter um SoftwareBitmap de um objeto CapturedFrame simplesmente acessando a propriedade SoftwareBitmap do objeto.It's trivial to get a SoftwareBitmap from a CapturedFrame object by simply accessing the SoftwareBitmap property of the object. No entanto, a maioria dos formatos de codificação não dá suporte para SoftwareBitmap com AdvancedPhotoCapture. Portanto, você deve verificar se a propriedade não é nula antes de usá-la.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;
}

Na versão atual, o único formato de codificação que dá suporte a SoftwareBitmap para AdvancedPhotoCapture é o NV12 descompactado.In the current release, the only encoding format that supports SoftwareBitmap for AdvancedPhotoCapture is uncompressed NV12. Portanto, se você quiser usar esse recurso, especifique essa codificação quando chamar 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));

É claro que você pode sempre salvar a imagem em um arquivo e, em seguida, carregar o arquivo em um SoftwareBitmap em uma etapa separada.Of course, you can always save the image to a file and then load the file into a SoftwareBitmap in a separate step. Para obter mais informações sobre como trabalhar com SoftwareBitmap, consulte Criar, editar e salvar imagens de bitmap.For more information about working with SoftwareBitmap, see Create, edit, and save bitmap images.

Salvar um CapturedFrame em um arquivoSave a CapturedFrame to a file

A classe CapturedFrame implementa a interface IInputStream, para que possa ser usada como entrada para um BitmapDecoder e depois um BitmapEncoder pode ser usado para gravar os dados da imagem em disco.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.

No exemplo a seguir, uma nova pasta na biblioteca de imagens do usuário é criada e um arquivo é criado dentro dessa pasta.In the following example, a new folder in the user's pictures library is created and a file is created within this folder. Observe que seu aplicativo precisará incluir a funcionalidade Biblioteca de Imagens no arquivo de manifesto do aplicativo para acessar esse diretório.Note that your app will need to include the Pictures Library capability in your app manifest file in order to access this directory. Depois, um fluxo do arquivo é aberto no arquivo especificado.A file stream is then opened to the specified file. Em seguida, o BitmapDecoder.CreateAsync é chamado para criar o decodificador do CapturedFrame.Next, the BitmapDecoder.CreateAsync is called to create the decoder from the CapturedFrame. Em seguida, CreateForTranscodingAsync cria um codificador a partir do fluxo do arquivo e o decodificador.Then CreateForTranscodingAsync creates an encoder from the file stream and the decoder.

As próximas etapas codificam a orientação da foto no arquivo de imagem usando os valores de BitmapProperties do codificador.The next steps encode the orientation of the photo into the image file by using the BitmapProperties of the encoder. Para obter mais informações sobre como lidar com a orientação ao capturar imagens, consulte Tratar a orientação do dispositivo com MediaCapture.For more information about handling orientation when capturing images, see Handle device orientation with MediaCapture.

Por fim, a imagem é gravada em um arquivo com uma chamada para 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;
}