Acquisire foto e video con l'interfaccia utente della fotocamera predefinita di Windows

Questo articolo descrive come usare la classe CameraCaptureUI per acquisire foto o video usando l'interfaccia utente della fotocamera integrata in Windows. Questa funzionalità è facile da usare. Consente all'app di ottenere una foto o un video acquisiti dall'utente con poche righe di codice.

Se si vuole fornire un'interfaccia utente della fotocamera personalizzata o se lo scenario richiede un controllo più affidabile e di basso livello dell'operazione di acquisizione, si deve usare la classe MediaCapture e implementare l'esperienza di acquisizione. Per ulteriori informazioni, vedere Acquisizione di base di foto, video e audio con MediaCapture.

Nota

Non è necessario specificare le funzionalità webcammicrofono nel file manifesto dell'app se l'app usa solo CameraCaptureUI. In tal caso, l'app verrà visualizzata nelle impostazioni di privacy della fotocamera del dispositivo, ma anche se l'utente nega l'accesso alla fotocamera all'app, questo non impedirà a CameraCaptureUI di acquisire contenuti multimediali.

Questo avviene perché l'app fotocamera integrata di Windows è un'app di prima parte attendibile che richiede all'utente di avviare l'acquisizione di foto, audio e video con una pressione del pulsante. L'app potrebbe non riuscire la certificazione del Kit di certificazione delle applicazioni Windows quando viene inviata a Microsoft Store se si specificano le funzionalità della webcam o del microfono quando si usa CameraCaptureUI come unico meccanismo di acquisizione foto.

Si devono specificare le funzionalità webcam o microfono nel file manifesto dell'app se si usa MediaCapture per acquisire audio, foto o video a livello di codice.

Acquisire una foto con CameraCaptureUI

Per usare l'interfaccia utente di acquisizione della fotocamera, includere lo spazio dei nomi Windows.Media.Capture nel progetto. Per eseguire operazioni sui file con il file di immagine restituito, includere 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;

Per acquisire una foto, creare un nuovo oggetto CameraCaptureUI. Usando la proprietà PhotoSettings dell'oggetto, si possono specificare le proprietà per la foto restituita, ad esempio il formato immagine della foto. Per impostazione predefinita, l'interfaccia utente di acquisizione della fotocamera supporta il ritaglio della foto prima che venga restituita. Questa opzione può essere disabilitata con la proprietà AllowCropping. Questo esempio imposta CroppedSizeInPixels per richiedere che l'immagine restituita sia 200 x 200 in pixel.

Nota

Il ritaglio delle immagini CameraCaptureUI non è supportato per i dispositivi nella famiglia di dispositivi mobili. Il valore della proprietà pllowCropping viene ignorato quando l'app è in esecuzione in questi dispositivi.

Chiamare CaptureFileAsync e specificare CameraCaptureUIMode.Photo per specificare che deve essere acquisita una foto. Il metodo restituisce un'istanza StorageFile contenente l'immagine se l'acquisizione ha esito positivo. Se l'utente annulla l'acquisizione, l'oggetto restituito è 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;
}

StorageFile contenente la foto acquisita viene assegnato un nome generato dinamicamente e salvato nella cartella locale dell'app. Per organizzare meglio le foto acquisite, si può spostare il file in una cartella diversa.

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();

Per usare la foto nell'app, si può creare un oggetto SoftwareBitmap che può essere usato con diverse funzionalità dell'app Universal Windows.

In primo luogo, includere lo spazio dei nomi Windows.Graphics.Imaging nel progetto.

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;

Chiamare OpenAsync per ottenere un flusso dal file immagine. Chiamare BitmapDecoder.CreateAsync per ottenere un decodificatore bitmap per il flusso. Chiamare quindi GetSoftwareBitmap per ottenere una rappresentazione SoftwareBitmap dell'immagine.

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();

Per visualizzare l'immagine nell'interfaccia utente, dichiarare un controllo Image nella pagina XAML.

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

Per usare la bitmap software nella pagina XAML, includere lo spazio dei nomi usando Windows.UI.Xaml.Media.Imaging nel progetto.

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

Il controllo Image richiede che l'origine immagine sia in formato BGRA8 con alfa premoltiplicato o nessun alfa. Chiamare il metodo statico SoftwareBitmap.Convert per creare una nuova bitmap software con il formato desiderato. Creare quindi un nuovo oggetto SoftwareBitmapSource e chiamarlo SetBitmapAsync per assegnare la bitmap software all'origine. Infine, impostare la Sorgente del controllo immagine per visualizzare la foto acquisita nell'interfaccia utente.

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

Acquisire un video con CameraCaptureUI

Per acquisire un video, creare un nuovo oggetto CameraCaptureUI. Usando la proprietà VideoSettings dell'oggetto, è possibile specificare le proprietà per il video restituito, ad esempio il formato del video.

Chiamare CaptureFileAsync e specificare Video per acquisire un video. Il metodo restituisce un'istanza StorageFile contenente il video se l'acquisizione ha esito positivo. Se si annulla l'acquisizione, l'oggetto restituito è 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;
}

Le operazioni eseguite con il file video acquisito dipendono dallo scenario per l'app. Il resto di questo articolo illustra come creare rapidamente una composizione multimediale da uno o più video acquisiti e mostrarlo nell'interfaccia utente.

Aggiungere prima di tutto un controllo MediaPlayerElement in cui la composizione video verrà visualizzata nella pagina XAML.

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

Quando il file video viene restituito dall'interfaccia utente di acquisizione della fotocamera, creare un nuovo oggetto MediaSource chiamando CreateFromStorageFile. Chiamare il metodo Play del MediaPlayer predefinito associato con MediaPlayerElement per riprodurre il video.

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