Capturar fotos e vídeos com a interface do usuário da câmera interna do Windows

Este artigo descreve como usar a classe CameraCaptureUI para capturar fotos ou vídeos usando a interface do usuário da câmera incorporada ao Windows. Esse recurso é fácil de usar. Ele permite que seu aplicativo obtenha uma foto ou vídeo capturado pelo usuário com apenas algumas linhas de código.

Se você quiser fornecer sua própria interface do usuário da câmera ou se seu cenário exigir um controle mais robusto e de baixo nível da operação de captura, use a classe MediaCapture e implemente sua própria experiência de captura. Para obter mais informações, consulte Captura básica de foto, vídeo e áudio com o MediaCapture.

Observação

Você não deve especificar as funcionalidades de webcam nem microfone no arquivo de manifesto do aplicativo se o aplicativo usar apenas CameraCaptureUI. Se você fizer isso, seu aplicativo será exibido nas configurações de privacidade da câmera do dispositivo, mas mesmo que o usuário negue o acesso da câmera ao seu aplicativo, isso não impedirá que o CameraCaptureUI capture a mídia.

Isso ocorre porque o aplicativo de câmera interno do Windows é um aplicativo de terceiros confiável que exige que o usuário inicie a captura de foto, áudio e vídeo pressionando um botão. Seu aplicativo poderá falhar na certificação do Kit de Certificação de Aplicativos do Windows quando enviado à Microsoft Store se você especificar os recursos de webcam ou microfone ao usar CameraCaptureUI como seu único mecanismo de captura de fotos.

Você deve especificar os recursos de webcam ou microfone no arquivo de manifesto do aplicativo se estiver usando o MediaCapture para capturar áudio, fotos ou vídeo programaticamente.

Capturar uma foto com CameraCaptureUI

Para usar a interface do usuário de captura com câmera, inclua o namespace Windows.Media.Capture em seu projeto. Para as operações de arquivo com o arquivo de imagem retornado, inclua Windows.Storage.

using Windows.Media.Capture;
using Windows.Storage;
#include <winrt/Windows.Media.Capture.h>
#include <winrt/Windows.Media.Playback.h>
#include <winrt/Windows.Storage.h>
using namespace winrt;
using namespace Windows::Media::Capture;
using namespace Windows::Storage;

Para capturar uma foto, crie um novo objeto CameraCaptureUI. Usando a propriedade PhotoSettings do objeto, você pode especificar propriedades para a foto retornada, como o formato de imagem da foto. Por padrão, a interface do usuário de captura de câmera dá suporte ao corte da foto antes de ser retornada. Isso pode ser desabilitado com a propriedade AllowCropping . Este exemplo define CroppedSizeInPixels para solicitar que a imagem retornada seja de 200 x 200 pixels.

Observação

Não há suporte para corte de imagem na CameraCaptureUI para dispositivos na família de dispositivos móveis. O valor da propriedade AllowCropping é ignorado quando seu aplicativo é executado nesses dispositivos.

Chame CaptureFileAsync e especifique CameraCaptureUIMode.Photo para especificar que uma foto deve ser capturada. O método retorna uma instância StorageFile que conterá a imagem se a captura for bem-sucedida. Se o usuário cancelar a captura, o objeto retornado será nulo.

CameraCaptureUI captureUI = new CameraCaptureUI();
captureUI.PhotoSettings.Format = CameraCaptureUIPhotoFormat.Jpeg;
captureUI.PhotoSettings.CroppedSizeInPixels = new Size(200, 200); 

StorageFile photo = await captureUI.CaptureFileAsync(CameraCaptureUIMode.Photo);

if (photo == null)
{
    // User cancelled photo capture
    return;
}
CameraCaptureUI captureUI;
captureUI.PhotoSettings().Format(CameraCaptureUIPhotoFormat::Jpeg);
captureUI.PhotoSettings().CroppedSizeInPixels({ 200, 200 });

StorageFile photo = co_await captureUI.CaptureFileAsync(CameraCaptureUIMode::Photo);

if (!photo)
{
    // User cancelled photo capture
    co_return;
}

É fornecido um nome gerado dinamicamente ao StorageFile que contém a foto capturada e salvo na pasta local do aplicativo. Para organizar melhor suas fotos capturadas, você pode mover o arquivo para uma pasta diferente.

StorageFolder destinationFolder = 
    await ApplicationData.Current.LocalFolder.CreateFolderAsync("ProfilePhotoFolder", 
        CreationCollisionOption.OpenIfExists);

await photo.CopyAsync(destinationFolder, "ProfilePhoto.jpg", NameCollisionOption.ReplaceExisting);
await photo.DeleteAsync();
StorageFolder destinationFolder =
    co_await ApplicationData::Current().LocalFolder().CreateFolderAsync(L"ProfilePhotoFolder",
        CreationCollisionOption::OpenIfExists);

co_await photo.CopyAsync(destinationFolder, L"ProfilePhoto.jpg", NameCollisionOption::ReplaceExisting);
co_await photo.DeleteAsync();

Para usar sua foto em seu aplicativo, talvez você queira criar um objeto SoftwareBitmap que pode ser usado com vários recursos diferentes de aplicativo Universal do Windows.

Primeiro, inclua o namespace Windows.Graphics.Imaging em seu projeto.

using Windows.Storage.Streams;
using Windows.Graphics.Imaging;
#include <winrt/Windows.Graphics.Imaging.h>
#include <winrt/Windows.Storage.Streams.h>
using namespace Windows::Graphics::Imaging;
using namespace Windows::Storage::Streams;

Chame OpenAsync para obter um fluxo do arquivo de imagem. Chame BitmapDecoder.CreateAsync para obter um decodificador de bitmap para o fluxo. Em seguida, chame GetSoftwareBitmap para obter uma representação SoftwareBitmap da imagem.

IRandomAccessStream stream = await photo.OpenAsync(FileAccessMode.Read);
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
SoftwareBitmap softwareBitmap = await decoder.GetSoftwareBitmapAsync();
IRandomAccessStream stream = co_await photo.OpenAsync(FileAccessMode::Read);
BitmapDecoder decoder = co_await BitmapDecoder::CreateAsync(stream);
SoftwareBitmap softwareBitmap = co_await decoder.GetSoftwareBitmapAsync();

Para exibir a imagem na interface do usuário, declare um controle Image na página XAML.

<Image x:Name="imageControl" Width="200" Height="200"/>
<Image x:Name="imageControl" Width="200" Height="200"/>

Para usar o bitmap de software na página XAML, inclua o namespace Windows.UI.Xaml.Media.Imaging em uso em seu projeto.

using Windows.UI.Xaml.Media.Imaging;
#include <winrt/Windows.UI.Xaml.Media.Imaging.h>
using namespace Windows::UI::Xaml::Media::Imaging;

O controle Imagem requer que a origem da imagem esteja no formato BGRA8 com alfa pré-multiplicado ou nenhum alfa. Chame o método estático SoftwareBitmap.Convert para criar um novo bitmap de software com o formato desejado. Em seguida, crie um novo objeto SoftwareBitmapSource e chame-o de SetBitmapAsync para atribuir o bitmap de software à origem. Por fim, defina a propriedade Image do controle Source para exibir a foto capturada na interface do usuário.

SoftwareBitmap softwareBitmapBGR8 = SoftwareBitmap.Convert(softwareBitmap,
        BitmapPixelFormat.Bgra8, 
        BitmapAlphaMode.Premultiplied);

SoftwareBitmapSource bitmapSource = new SoftwareBitmapSource();
await bitmapSource.SetBitmapAsync(softwareBitmapBGR8);

imageControl.Source = bitmapSource;
SoftwareBitmap softwareBitmapBGR8 = SoftwareBitmap::Convert(softwareBitmap,
    BitmapPixelFormat::Bgra8,
    BitmapAlphaMode::Premultiplied);

SoftwareBitmapSource bitmapSource;
co_await bitmapSource.SetBitmapAsync(softwareBitmapBGR8);

imageControl().Source(bitmapSource);

Capturar um vídeo com CameraCaptureUI

Para capturar um vídeo, crie um novo objeto CameraCaptureUI. Usando a propriedade VideoSettings do objeto, você pode especificar propriedades para o vídeo retornado, como o formato do vídeo.

Chame CaptureFileAsync e especifique Vídeo para capturar um vídeo. O método retorna a uma instância StorageFile que conterá o vídeo se a captura for bem-sucedida. Se você cancelar a captura, o objeto retornado será nulo.

CameraCaptureUI captureUI = new CameraCaptureUI();
captureUI.VideoSettings.Format = CameraCaptureUIVideoFormat.Mp4;

StorageFile videoFile = await captureUI.CaptureFileAsync(CameraCaptureUIMode.Video);

if (videoFile == null)
{
    // User cancelled photo capture
    return;
}
CameraCaptureUI captureUI;
captureUI.VideoSettings().Format(CameraCaptureUIVideoFormat::Mp4);

StorageFile videoFile = co_await captureUI.CaptureFileAsync(CameraCaptureUIMode::Video);

if (!videoFile)
{
    // User cancelled photo capture
    co_return;
}

O que fazer com o arquivo de vídeo capturado depende do cenário para o seu aplicativo. O restante deste artigo mostra como criar rapidamente uma composição de mídia de um ou mais vídeos capturados e mostrá-la em sua interface do usuário.

Primeiro, adicione um controle MediaPlayerElement no qual a composição de vídeo será exibida em sua página XAML.

<MediaPlayerElement x:Name="mediaPlayerElement" Width="320" Height="240" AreTransportControlsEnabled="True"/>

Quando o arquivo de vídeo retornar da interface do usuário de captura da câmera, crie um novo MediaSource chamando CreateFromStorageFile. Chame o método Reproduzir do MediaPlayer padrão associado a MediaPlayerElement para reproduzir o vídeo.

mediaPlayerElement.Source = MediaSource.CreateFromStorageFile(videoFile);
mediaPlayerElement.MediaPlayer.Play();
mediaPlayerElement().Source(MediaSource::CreateFromStorageFile(videoFile));
mediaPlayerElement().MediaPlayer().Play();