Capturar fotografías y vídeos con la interfaz de usuario de la cámara integrada de Windows

En este artículo se describe cómo usar la clase CameraCaptureUI para capturar fotos o vídeos mediante la interfaz de usuario de la cámara integrada en Windows. Esta característica es fácil de usar. Permite que la aplicación obtenga una foto o un vídeo capturados por el usuario con solo unas pocas líneas de código.

Si desea proporcionar su propia interfaz de usuario de cámara, o si su escenario requiere un control más sólido y de bajo nivel de la operación de captura, debe usar la clase MediaCapture e implementar su propia experiencia de captura. Para obtener más información, consulta Captura básica de fotos, audio y vídeo con MediaCapture.

Nota

No debes especificar las funcionalidades de cámara web ni micrófono en el archivo de manifiesto de la aplicación si tu aplicación solo usa CameraCaptureUI. Si lo haces, la aplicación se mostrará en la configuración de privacidad de la cámara del dispositivo, pero incluso si el usuario deniega el acceso de la cámara a la aplicación, esto no impedirá que CameraCaptureUI capture medios.

Esto es porque la aplicación de cámara integrada de Windows es una aplicación de origen de confianza que requiere que el usuario inicie la captura de fotos, audio y vídeo con la presión de un botón. La aplicación puede producir un error en la certificación del Kit de certificación de aplicaciones de Windows cuando se envía a Microsoft Store si especificas las funcionalidades de cámara web o micrófono al usar CameraCaptureUI como único mecanismo de captura de fotos.

Debes especificar las funcionalidades de cámara web o micrófono en el archivo de manifiesto de la aplicación si usas MediaCapture para capturar audio, fotos o vídeo mediante programación.

Capturar una foto con CameraCaptureUI

Para usar la interfaz de usuario de captura de cámara, incluye el espacio de nombres Windows.Media.Capture en el proyecto. Para realizar operaciones de archivo con el archivo de imagen devuelto, incluye 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 una foto, crea un objeto CameraCaptureUI nuevo. Mediante el uso de la propiedad PhotoSettings del objeto, puede especificar propiedades para la foto devuelta, como el formato de imagen de la foto. De forma predeterminada, la interfaz de usuario de captura de cámara admite el recorte de la foto antes de que se devuelva. Esto se puede deshabilitar con la propiedad AllowCropping . Este ejemplo establece CroppedSizeInPixels para solicitar que la imagen devuelta sea de 200 x 200 píxeles.

Nota

El recorte de imágenes en CameraCaptureUI no es compatible con los dispositivos de la familia de dispositivos móviles. El valor de la propiedad AllowCropping se omite cuando se ejecuta la aplicación en estos dispositivos.

Realiza una llamada a CaptureFileAsync y especifica CameraCaptureUIMode.Photo para especificar que se debe capturar una foto. El método devuelve una instancia StorageFile que contiene la imagen si la captura se realiza correctamente. Si el usuario cancela la captura, el objeto devuelto es null.

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;
}

A la clase StorageFile que contiene la foto capturada se le asigna un nombre generado dinámicamente y se guarda en la carpeta local de la aplicación. Para organizar mejor las fotos capturadas, puede mover el archivo a otra carpeta.

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 la foto en la aplicación, tal vez quieras crear un objeto SoftwareBitmap que se puede usar con varias características diferentes de una aplicación universal de Windows.

En primer lugar, incluya el espacio de nombres Windows.Graphics.Imaging en el proyecto.

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;

Realiza una llamada a OpenAsync para obtener una secuencia del archivo de imagen. Realiza una llamada a BitmapDecoder.CreateAsync para obtener un descodificador de mapa de bits de la secuencia. A continuación, llame a GetSoftwareBitmap para obtener una representación de SoftwareBitmap de la imagen.

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 mostrar la imagen en la interfaz de usuario, declara un control de Image en la página XAML.

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

Para usar el mapa de bits de software en tu página XAML, incluye el espacio de nombres Windows.UI.Xaml.Media.Imaging de "using" en el proyecto.

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

El control Image requiere que el origen de la imagen esté en formato BGRA8 con alfa premultiplido o sin alfa. Llame al método estático SoftwareBitmap.Convert para crear un mapa de bits de software con el formato deseado. A continuación, cree un nuevo objeto SoftwareBitmapSource y llámalo SetBitmapAsync para asignar el mapa de bits de software al origen. Por último, establece el control de Image de la propiedad Source del control para mostrar la foto capturada en la interfaz de usuario.

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 un vídeo con CameraCaptureUI

Para capturar un vídeo, crea un objeto CameraCaptureUI nuevo. Mediante el uso de la propiedad VideoSettings del objeto, puede especificar propiedades para el vídeo devuelto, como el formato del vídeo.

Llame a CaptureFileAsync y especifique Vídeo para capturar un vídeo. El método devuelve una instancia StorageFile que contiene el vídeo si la captura se realiza correctamente. Si cancela la captura, el objeto devuelto es NULL.

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;
}

Qué hacer con el archivo de vídeo capturado depende del escenario para la aplicación. El resto de este artículo muestra cómo crear rápidamente una composición multimedia de uno o más vídeos capturados y mostrarla en la interfaz de usuario.

En primer lugar, agrega un control MediaPlayerElement en el que la composición de vídeo se mostrará en tu página XAML.

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

Cuando el archivo de vídeo vuelva de la interfaz de usuario de captura de cámara, cree un nuevo mediaSource llamando a CreateFromStorageFile. Llame al método Play del objeto MediaPlayer predeterminado asociado al objeto MediaPlayerElement para reproducir el vídeo.

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