Afficher l’aperçu de l’appareil photo
Cet article explique comment afficher rapidement le flux d’aperçu de la caméra dans une page XAML dans une application plateforme Windows universelle (UWP). La création d’une application qui capture des photos et des vidéos à l’aide de l’appareil photo vous oblige à effectuer des tâches telles que la gestion de l’orientation de l’appareil et de l’appareil photo ou la définition d’options d’encodage pour le fichier capturé. Pour certains scénarios d’application, vous pouvez simplement afficher le flux d’aperçu de la caméra sans vous soucier de ces autres considérations. Cet article vous montre comment procéder avec un minimum de code. Notez que vous devez toujours arrêter correctement le flux d’aperçu lorsque vous avez terminé avec celui-ci en suivant les étapes ci-dessous.
Pour plus d’informations sur l’écriture d’une application d’appareil photo qui capture des photos ou des vidéos, voir Photo de base, Vidéo et Capture audio avec MediaCapture.
Ajouter des déclarations de capacités au manifeste de l’application
Pour que votre application puisse accéder à l’appareil photo d’un appareil, vous devez déclarer que votre application utilise les capacités de la webcam et du microphone de l’appareil.
Ajouter des fonctionnalités au manifeste de l’application
- Dans Microsoft Visual Studio, dans Explorateur de solutions, ouvrez le concepteur du manifeste de l’application en double-cliquant sur l’élément package.appxmanifest.
- Sélectionnez l’onglet Fonctionnalités.
- Cochez la case Webcam et la case Microphone.
Ajouter un élément CaptureElement à votre page
Utilisez un CaptureElement pour afficher le flux d’aperçu dans votre page XAML.
<CaptureElement Name="PreviewControl" Stretch="Uniform"/>
Utiliser MediaCapture pour démarrer le flux d’aperçu
L’objet MediaCapture est l’interface de votre application pour la caméra de l’appareil. Cette classe est membre de l’espace de noms Windows.Media.Capture. L’exemple de cet article utilise également des API à partir des espaces de noms Windows.ApplicationModel et System.Threading.Tasks , en plus de celles incluses par le modèle de projet par défaut.
Ajoutez des directives using pour inclure les espaces de noms suivants dans le fichier .cs de votre page.
//MainPage.xaml.cs
using Windows.UI.Core;
using Windows.UI.Xaml.Navigation;
using Windows.Media.Capture;
using Windows.ApplicationModel;
using System.Threading.Tasks;
using Windows.System.Display;
using Windows.Graphics.Display;
Déclarez une variable membre de classe pour l’objet MediaCapture et une valeur booléenne pour déterminer si l’appareil photo est actuellement en préversion.
MediaCapture mediaCapture;
bool isPreviewing;
Déclarez une variable de type DisplayRequest qui sera utilisée pour vous assurer que l’affichage ne s’active pas pendant l’exécution de l’aperçu.
DisplayRequest displayRequest = new DisplayRequest();
Créez une méthode d’assistance pour démarrer l’aperçu de la caméra, appelée StartPreviewAsync dans cet exemple. Selon le scénario de votre application, vous pouvez appeler cela à partir du gestionnaire d’événements OnNavigatedTo appelé lorsque la page est chargée ou attendez et lancez l’aperçu en réponse aux événements d’interface utilisateur.
Créez une instance de la classe MediaCapture et appelez InitializeAsync pour initialiser l’appareil de capture. Cette méthode peut échouer, sur les appareils qui n’ont pas de caméra par exemple. Vous devez donc l’appeler à partir d’un bloc try . Une exception UnauthorizedAccessException est levée lorsque vous tentez d’initialiser la caméra si l’utilisateur a désactivé l’accès à la caméra dans les paramètres de confidentialité de l’appareil. Vous verrez également cette exception pendant le développement si vous avez négligé d’ajouter les fonctionnalités appropriées à votre manifeste d’application.
Important sur certaines familles d’appareils, une invite de consentement de l’utilisateur s’affiche à l’utilisateur avant que votre application n’ait accès à la caméra de l’appareil. Pour cette raison, vous devez uniquement appeler MediaCapture.InitializeAsync à partir du thread d’interface utilisateur principal. La tentative d’initialisation de la caméra à partir d’un autre thread peut entraîner un échec d’initialisation.
Remarque
Windows permet aux utilisateurs d’accorder ou de refuser l’accès à la caméra de l’appareil dans l’application Paramètres Windows, sous Confidentialité et Sécurité -> Caméra. Lors de l’initialisation du périphérique de capture, les applications doivent vérifier s’ils ont accès à la caméra et gérer le cas où l’accès est refusé par l’utilisateur. Pour plus d’informations, consultez Gérer le paramètre de confidentialité de la caméra Windows.
Connectez MediaCapture à CaptureElement en définissant la propriété Source. Démarrez la préversion en appelant StartPreviewAsync. Cette méthode lève une exception FileLoadException si une autre application a un contrôle exclusif de l’appareil de capture. Consultez la section suivante pour plus d’informations sur l’écoute des modifications apportées au contrôle exclusif.
Appelez RequestActive pour vous assurer que l’appareil n’est pas en veille pendant l’exécution de la préversion. Enfin, définissez la propriété DisplayInformation.AutoRotationPreferences sur Paysage pour empêcher l’interface utilisateur et l’élément CaptureElement de pivoter lorsque l’utilisateur modifie l’orientation de l’appareil. Pour plus d’informations sur la gestion des modifications d’orientation des appareils, consultez Gérer l’orientation des appareils avec MediaCapture.
private async Task StartPreviewAsync()
{
try
{
mediaCapture = new MediaCapture();
await mediaCapture.InitializeAsync();
displayRequest.RequestActive();
DisplayInformation.AutoRotationPreferences = DisplayOrientations.Landscape;
}
catch (UnauthorizedAccessException)
{
// This will be thrown if the user denied access to the camera in privacy settings
ShowMessageToUser("The app was denied access to the camera");
return;
}
try
{
PreviewControl.Source = mediaCapture;
await mediaCapture.StartPreviewAsync();
isPreviewing = true;
}
catch (System.IO.FileLoadException)
{
mediaCapture.CaptureDeviceExclusiveControlStatusChanged += _mediaCapture_CaptureDeviceExclusiveControlStatusChanged;
}
}
Gérer les modifications dans le contrôle exclusif
Comme indiqué dans la section précédente, StartPreviewAsync lève une exception FileLoadException si une autre application a un contrôle exclusif de l’appareil de capture. À compter de Windows 10, version 1703, vous pouvez inscrire un gestionnaire pour l’événement MediaCapture.CaptureDeviceExclusiveControlStatusChanged , déclenché chaque fois que l’état de contrôle exclusif de l’appareil change. Dans le gestionnaire de cet événement, vérifiez la propriété MediaCaptureDeviceExclusiveControlStatusChangedEventArgs.Status pour voir l’état actuel. Si le nouvel état est SharedReadOnlyAvailable, vous savez que vous ne pouvez pas démarrer la préversion et que vous souhaiterez peut-être mettre à jour votre interface utilisateur pour alerter l’utilisateur. Si le nouvel état est ExclusiveControlAvailable, vous pouvez réessayer de démarrer l’aperçu de l’appareil photo.
private async void _mediaCapture_CaptureDeviceExclusiveControlStatusChanged(MediaCapture sender, MediaCaptureDeviceExclusiveControlStatusChangedEventArgs args)
{
if (args.Status == MediaCaptureDeviceExclusiveControlStatus.SharedReadOnlyAvailable)
{
ShowMessageToUser("The camera preview can't be displayed because another app has exclusive access");
}
else if (args.Status == MediaCaptureDeviceExclusiveControlStatus.ExclusiveControlAvailable && !isPreviewing)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
await StartPreviewAsync();
});
}
}
Arrêter le flux d’aperçu
Lorsque vous avez terminé d’utiliser le flux d’aperçu, vous devez toujours arrêter le flux et supprimer correctement les ressources associées pour vous assurer que l’appareil photo est disponible pour d’autres applications sur l’appareil. Les étapes requises pour arrêter le flux d’aperçu sont les suivantes :
- Si l’appareil photo est actuellement en préversion, appelez StopPreviewAsync pour arrêter le flux d’aperçu. Une exception est levée si vous appelez StopPreviewAsync pendant que la préversion n’est pas en cours d’exécution.
- Définissez la propriété Source de CaptureElement sur Null. Utilisez CoreDispatcher.RunAsync pour vous assurer que cet appel est exécuté sur le thread d’interface utilisateur.
- Appelez la méthode Dispose de l’objet MediaCapture pour libérer l’objet. Là encore, utilisez CoreDispatcher.RunAsync pour vous assurer que cet appel est exécuté sur le thread d’interface utilisateur.
- Définissez la variable membre MediaCapture sur Null.
- Appelez RequestRelease pour autoriser l’écran à désactiver lorsqu’il est inactif.
private async Task CleanupCameraAsync()
{
if (mediaCapture != null)
{
if (isPreviewing)
{
await mediaCapture.StopPreviewAsync();
}
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
PreviewControl.Source = null;
if (displayRequest != null)
{
displayRequest.RequestRelease();
}
mediaCapture.Dispose();
mediaCapture = null;
});
}
}
Vous devez arrêter le flux d’aperçu lorsque l’utilisateur quitte votre page en remplaçant la méthode OnNavigatedFrom.
protected async override void OnNavigatedFrom(NavigationEventArgs e)
{
await CleanupCameraAsync();
}
Vous devez également arrêter correctement le flux d’aperçu lorsque votre application est suspendue. Pour ce faire, inscrivez un gestionnaire pour l’événement Application.Suspending dans le constructeur de votre page.
public MainPage()
{
this.InitializeComponent();
Application.Current.Suspending += Application_Suspending;
}
Dans le gestionnaire d’événements Suspending, vérifiez d’abord que la page est affichée dans frame de l’application en comparant le type de page à la propriété CurrentSourcePageType. Si la page n’est pas en cours d’affichage, l’événement OnNavigatedFrom doit déjà avoir été déclenché et le flux d’aperçu s’arrête. Si la page est en cours d’affichage, obtenez un objet SuspendingDeferral à partir des arguments d’événement passés dans le gestionnaire pour vous assurer que le système ne suspend pas votre application tant que le flux d’aperçu n’a pas été arrêté. Après avoir arrêté le flux, appelez la méthode Complete du report pour permettre au système de continuer à suspendre votre application.
private async void Application_Suspending(object sender, SuspendingEventArgs e)
{
// Handle global application events only if this page is active
if (Frame.CurrentSourcePageType == typeof(MainPage))
{
var deferral = e.SuspendingOperation.GetDeferral();
await CleanupCameraAsync();
deferral.Complete();
}
}