Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Windows. Graphics.Capture espace de noms fournit des API pour acquérir des images à partir d’une fenêtre d’affichage ou d’application, pour créer des flux vidéo ou des instantanés pour créer des expériences collaboratives et interactives.
Avec la capture d’écran, les développeurs appellent l’interface utilisateur système sécurisée pour que les utilisateurs finaux sélectionnent l’affichage ou la fenêtre d’application à capturer, et une bordure de notification jaune est dessinée par le système autour de l’élément capturé activement. Dans le cas de plusieurs sessions de capture simultanées, une bordure jaune est dessinée autour de chaque élément capturé.
Note
Les API de capture d’écran ne sont prises en charge que sur les appareils de bureau Windows et les casques immersifs Windows Mixed Reality.
Cet article décrit la capture d’une seule image de la fenêtre d’affichage ou d’application.
Vérifier si la capture d’écran est prise en charge
Avant de tenter de capturer, vérifiez si l’appareil actuel prend en charge la capture d’écran. Utilisez la méthode IsSupported sur GraphicsCaptureSession pour déterminer si la capture d’écran est disponible :
// Check if screen capture is supported
if (!GraphicsCaptureSession.IsSupported())
{
// Hide capture UI
CaptureControlsPanel.Visibility = Visibility.Collapsed;
PreviewPlaceholderText.Text = "Screen capture isn't supported on this device.";
UpdateStatus("Screen capture isn't supported on this device.");
return;
}
Il existe plusieurs raisons pour lesquelles la capture d’écran peut ne pas être prise en charge, notamment si l’appareil ne répond pas à la configuration matérielle requise.
Lancer l’interface utilisateur système pour démarrer la capture d’écran
Utilisez la classe GraphicsCapturePicker pour appeler l’interface utilisateur du sélecteur de système. L’utilisateur final utilise cette interface utilisateur pour sélectionner la fenêtre d’affichage ou d’application à capturer. Le sélecteur retourne un GraphicsCaptureItem utilisé pour créer une session de capture.
Dans une application WinUI 3, vous devez initialiser le sélecteur avec le handle de fenêtre avant d’appeler PickSingleItemAsync :
// Launch picker and start capture
var picker = new GraphicsCapturePicker();
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
WinRT.Interop.InitializeWithWindow.Initialize(picker, hwnd);
GraphicsCaptureItem item = await picker.PickSingleItemAsync();
if (item != null)
{
StartCaptureInternal(item);
}
Créer un pool de trames de capture et une session de capture
À l’aide de GraphicsCaptureItem, créez un Direct3D11CaptureFramePool avec votre appareil D3D, un format de pixel pris en charge (DXGI_FORMAT_B8G8R8A8_UNORM), le nombre d’images souhaitées (qui peuvent être n’importe quel entier) et la taille d’image. La propriété Size de la classe GraphicsCaptureItem peut être utilisée comme taille de votre frame :
// Create frame pool and capture session
_framePool = Direct3D11CaptureFramePool.Create(
_canvasDevice,
CaptureDirectXPixelFormat.B8G8R8A8UIntNormalized,
BufferCount,
item.Size);
_session = _framePool.CreateCaptureSession(item);
Note
Sur les systèmes où Windows HD Color est activé, le format de pixel du contenu n'est pas nécessairement DXGI_FORMAT_B8G8R8A8_UNORM. Pour éviter un écrêtage excessif des pixels (c’est-à-dire que le contenu capturé semble délavé) lors de la capture de contenu HDR, il est recommandé d’utiliser DXGI_FORMAT_R16G16B16A16_FLOAT pour chaque composant du pipeline de capture, y compris dans le Direct3D11CaptureFramePool, ainsi que dans la destination cible, telle que CanvasBitmap. Selon le besoin, un traitement supplémentaire, tel que l’enregistrement au format de contenu HDR ou le mappage de tonalité HDR-to-SDR, peut être nécessaire. Cet article se concentre sur la capture de contenu SDR. Pour plus d’informations, consultez Utilisation de DirectX avec des affichages à plage dynamique élevée et une couleur avancée.
Une fois que l’utilisateur a explicitement donné son consentement pour capturer une fenêtre d’application ou s’afficher dans l’interface utilisateur système, l’objet GraphicsCaptureItem peut être associé à plusieurs sessions de capture. Ainsi, votre application peut choisir de capturer le même élément pour différentes expériences.
Acquérir des images de capture
Une fois votre pool d’images et votre session de capture créée, appelez StartCapture sur votre instance GraphicsCaptureSession pour informer le système de commencer à envoyer des trames de capture à votre application.
Pour acquérir ces images de capture, qui sont des objets Direct3D11CaptureFrame , utilisez l’événement Direct3D11CaptureFramePool.FrameArrived :
// Handle frame arrival
_framePool.FrameArrived += OnFrameArrived;
Il est recommandé d’éviter de faire du travail lourd sur le thread d’interface utilisateur pour FrameArrived, car cet événement se déclenche chaque fois qu’une nouvelle trame est disponible. Si vous choisissez d’écouter FrameArrived sur le thread d’interface utilisateur, gardez à l’esprit le travail que vous effectuez chaque fois que l’événement se déclenche.
Vous pouvez également extraire manuellement des images avec la méthode Direct3D11CaptureFramePool.TryGetNextFrame jusqu’à obtenir toutes les images dont vous avez besoin.
L’objet Direct3D11CaptureFrame contient les propriétés ContentSize, Surface et SystemRelativeTime. Le SystemRelativeTime est un temps basé sur QPC (QueryPerformanceCounter) qui peut être utilisé pour synchroniser d’autres éléments multimédias.
Traitement des trames capturées
Chaque image du Direct3D11CaptureFramePool est récupérée lors de l’appel à TryGetNextFrame, puis restituée en fonction de la durée de vie de l’objet Direct3D11CaptureFrame. Pour les applications managées, il est recommandé d’utiliser la méthode Direct3D11CaptureFrame.Dispose . Direct3D11CaptureFrame implémente IDisposable, de sorte que la suppression du frame retourne la mémoire tampon au pool.
Les applications ne doivent pas conserver de références aux objets Direct3D11CaptureFrame, ni conserver de références à la surface Direct3D sous-jacente après la restitution de l’image.
Dans cet exemple, chaque frame est converti en canvasBitmap, qui fait partie de la bibliothèque Win2D :
// Convert frame to Win2D bitmap and display
CanvasBitmap canvasBitmap = CanvasBitmap.CreateFromDirect3D11Surface(
_canvasDevice,
frame.Surface);
La surface Direct3D sous-jacente est toujours la taille spécifiée lors de la création (ou de la recréation) de Direct3D11CaptureFramePool. Si le contenu est plus grand que le cadre, il est rogné aux dimensions du cadre. Si le contenu est plus petit que le cadre, le reste du cadre contient des données non définies. Il est recommandé que les applications copient un sous-rectangle en utilisant la propriété ContentSize de cette Direct3D11CaptureFrame afin d’éviter d’afficher un contenu non défini.
Enregistrer une capture d’écran
Une fois que vous avez un CanvasBitmap, vous pouvez l’enregistrer en tant que fichier image. L’exemple suivant enregistre le cadre actuel sous la forme d’un fichier PNG à l’aide d’un FileSavePicker. Dans une application WinUI 3, vous devez initialiser le sélecteur avec le descripteur de fenêtre :
// Save screenshot
var savePicker = new FileSavePicker();
savePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
savePicker.SuggestedFileName = "screen-capture";
savePicker.FileTypeChoices.Add("PNG image", new List<string> { ".png" });
WinRT.Interop.InitializeWithWindow.Initialize(savePicker, _hwnd);
StorageFile? file = await savePicker.PickSaveFileAsync();
if (file is not null)
{
using var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite);
await frameToSave.SaveAsync(fileStream, CanvasBitmapFileFormat.Png, 1f);
}
Réagir pour capturer le redimensionnement d’élément ou l’appareil perdu
Pendant le processus de capture, les applications peuvent souhaiter modifier les aspects de leur Direct3D11CaptureFramePool. Cela inclut la fourniture d’un nouvel appareil Direct3D, la modification de la taille des mémoires tampons d’images, ou même la modification du nombre de mémoires tampons au sein du pool. Dans chacun de ces scénarios, la méthode Recréer sur l’objet Direct3D11CaptureFramePool est l’approche recommandée.
Lorsque Recreate est appelée, toutes les trames existantes sont supprimées. Cela permet d’empêcher la remise de cadres dont les surfaces Direct3D sous-jacentes appartiennent à un appareil auquel l’application peut ne plus avoir accès. Pour cette raison, il peut être judicieux de traiter toutes les trames en attente avant d’appeler Recréer.
Considérations relatives à WinUI 3
Lors de la migration du code de capture d’écran de UWP vers WinUI 3 (SDK d'application Windows), gardez à l’esprit les différences suivantes :
- Initialisation du handle de fenêtre — Les sélecteurs comme GraphicsCapturePicker et FileSavePicker doivent être initialisés à l’aide du handle de fenêtre en utilisant InitializeWithWindow. Pour plus d’informations, consultez Récupérer un descripteur de fenêtre (HWND).
- Les API de composition sur le thread d’interface utilisateur : dans WinUI 3, les opérations de surface CanvasComposition (telles que le dessin vers un CompositionDrawingSurface) doivent être distribuées au thread d’interface utilisateur à l’aide de DispatcherQueue.TryEnqueue. La capture d’images et la création d’images bitmap peuvent se produire sur le thread d’arrière-plan du pool d’images, mais la mise à jour du visuel de composition doit se produire sur le thread d’interface utilisateur.
-
Namespace change — Utilisez
Microsoft.UI.Composition,Microsoft.UI.Xaml.HostingetMicrosoft.UI.Dispatchingau lieu de leurs équivalentsWindows.UI. L’espace de nomsWindows.Graphics.Capturereste inchangé.
Voir aussi
- espace de noms Windows.Graphics.Capture
- Win2D pour WinUI 3
- Récupérer un handle de fenêtre (HWND)
- Graphiques : index des fonctionnalités de développement graphique pour les applications Windows
- Exemples de graphiques DirectX sur GitHub
Windows developer