Notes
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.
Créez des applications de plateforme Windows universelle (UWP) avec des animations lisses, une fréquence d’images élevée et une capture et une lecture multimédia hautes performances.
Rendre les animations lisses
Un aspect clé des applications UWP est des interactions fluides. Cela inclut les manipulations tactiles qui « collent à votre doigt », les transitions et animations lisses et les petits mouvements qui fournissent des commentaires d’entrée. Dans l’infrastructure XAML, il existe un thread appelé thread de composition dédié à la composition et à l’animation des éléments visuels d’une application. Étant donné que le thread de composition est distinct du thread d’interface utilisateur (le thread qui exécute le code du framework et du développeur), les applications peuvent obtenir une fréquence d’images cohérente et des animations lisses, quelles que soient les passes de disposition complexes ou les calculs étendus. Cette section montre comment utiliser le fil de composition pour maintenir les animations d’une application fluides. Pour plus d’informations sur les animations, consultez vue d’ensemble des animations. Pour en savoir plus sur l’augmentation de la réactivité d’une application tout en effectuant des calculs intensifs, consultez Conserver le thread d’interface utilisateur réactif.
Utilisez des animations indépendantes au lieu de dépendantes.
Les animations indépendantes peuvent être calculées de début à fin au moment de la création, car les modifications apportées à la propriété animée n’affectent pas le reste des objets d’une scène. Les animations indépendantes peuvent donc s’exécuter sur le thread de composition au lieu du thread d’interface utilisateur. Cela garantit qu’ils restent lisses, car le thread de composition est mis à jour à une cadence cohérente.
Tous ces types d’animations sont garantis d’être indépendants :
Animations d’objet à l’aide de cadres clés
Animations de durée nulle
Animations sur les propriétés Canvas.Left et Canvas.Top
Animations sur la propriété UIElement.Opacity
Animations vers des propriétés de type Brush lorsque la sous-propriété SolidColorBrush.Color est ciblée
Animations des UIElement suivantes propriétés lors du ciblage de sous-propriétés de ces types de valeurs de retour :
- RenderTransform
- Transform3D
- projection
- Capture
Les animations dépendantes affectent la disposition, ce qui ne peut donc pas être calculé sans entrée supplémentaire à partir du thread d’interface utilisateur. Les animations dépendantes incluent des modifications apportées aux propriétés comme Largeur et Hauteur. Par défaut, les animations dépendantes ne sont pas exécutées et nécessitent une inscription auprès du développeur de l’application. Lorsqu'elles sont activées, elles s'exécutent correctement si le thread de l'interface utilisateur reste débloqué, mais elles commencent à bégayer si l'infrastructure ou l'application effectue de nombreuses autres tâches sur le thread de l'interface utilisateur.
Presque toutes les animations de l’infrastructure XAML sont indépendantes par défaut, mais certaines actions peuvent être effectuées pour désactiver cette optimisation. Attention à ces scénarios en particulier :
- Définition de la propriété EnableDependentAnimation pour autoriser l’exécution d’une animation dépendante sur le thread d’interface utilisateur. Convertissez ces animations en version indépendante. Par exemple, animer ScaleTransform.ScaleX et ScaleTransform.ScaleY au lieu de Width et Height d’un objet. N’avez pas peur de mettre à l’échelle des objets tels que des images et du texte. Le cadre applique la mise à l’échelle bilinéaire uniquement lorsque le ScaleTransform est animé. L’image/le texte sera ré-rastérisé à la taille finale pour s'assurer qu’il est toujours net.
- Création de mises à jour par image, qui sont efficacement dépendantes des animations. Par exemple, l’application de transformations dans le gestionnaire de l’événement CompositonTarget.Rendering.
- Exécution d’une animation considérée indépendante dans un élément avec la propriété CacheMode
définie sur BitmapCache . Cela est considéré comme dépendant, car le cache doit être re-ratérisé pour chaque image.
Ne pas animer un WebView ou MediaPlayerElement
Le contenu web au sein d’un contrôle WebView n’est pas rendu directement par l’infrastructure XAML et nécessite un effort supplémentaire pour s'intégrer avec le reste de la scène. Ce travail supplémentaire s’ajoute lors de l’animation du contrôle autour de l’écran et peut potentiellement introduire des problèmes de synchronisation (par exemple, le contenu HTML peut ne pas se déplacer lors de la synchronisation avec le reste du contenu XAML sur la page). Lorsque vous devez animer un contrôle WebView , échangez-le avec un WebViewBrush pendant la durée de l’animation.
L’animation d’un MediaPlayerElement est également une mauvaise idée. Au-delà du détriment des performances, il peut provoquer des larmes ou d’autres artefacts dans le contenu vidéo en cours de lecture.
Note Les recommandations de cet article pour MediaPlayerElement s’appliquent également à MediaElement. MediaPlayerElement est disponible uniquement dans Windows 10 version 1607. Par conséquent, si vous créez une application pour une version précédente de Windows, vous devez utiliser MediaElement.
Utiliser des animations infinies avec parcimonie
La plupart des animations s’exécutent pendant une durée spécifiée, mais la définition de la propriété Timeline.Duration sur Forever permet à une animation de s’exécuter indéfiniment. Nous vous recommandons de réduire l’utilisation d’animations infinies, car elles consomment continuellement des ressources processeur et peuvent empêcher l’UC de passer à un état de faible alimentation ou d’inactivité, ce qui l’oblige à manquer de puissance plus rapidement.
L’ajout d’un gestionnaire pour CompositionTarget.Rendering est similaire à l’exécution d’une animation infinie. Normalement, le thread d’interface utilisateur est actif uniquement lorsqu’il y a du travail à effectuer, mais l’ajout d’un gestionnaire pour cet événement le force à s’exécuter à chaque image. Supprimez le gestionnaire lorsqu’il n’y a pas de travail à effectuer et réinscrivez-le lorsqu’il est nécessaire de nouveau.
Utiliser la bibliothèque d’animations
L’espace de noms Windows.UI.Xaml.Media.Animation comprend une bibliothèque d’animations hautes performances et lisses qui ont une apparence cohérente avec d’autres animations Windows. Les classes pertinentes ont « Thème » dans leur nom et sont décrites dans la vue d’ensemble des animations. Cette bibliothèque prend en charge de nombreux scénarios d’animation courants, tels que l’animation de la première vue de l’application et la création de transitions d’état et de contenu. Nous vous recommandons d’utiliser cette bibliothèque d’animations chaque fois que possible pour augmenter les performances et la cohérence de l’interface utilisateur UWP.
Note La bibliothèque d’animations ne peut pas animer toutes les propriétés possibles. Pour les scénarios XAML où la bibliothèque d’animations ne s’applique pas, consultez animations storyboarded.
Animez indépendamment les propriétés de CompositeTransform3D
Vous pouvez animer chaque propriété d’un CompositeTransform3D indépendamment, donc appliquer uniquement les animations dont vous avez besoin. Pour obtenir des exemples et plus d’informations, consultez UIElement.Transform3D. Pour plus d’informations sur l’animation des transformations, consultez animations scénarisées et animations par images clés et fonctions d'interpolation.
Optimiser les ressources multimédias
L’audio, la vidéo et les images sont des formes attrayantes de contenu que la majorité des applications utilisent. À mesure que les taux de capture multimédia augmentent et que le contenu passe de la définition standard à la haute définition, la quantité de ressources nécessaires pour stocker, décoder et lire ce contenu augmente. L’infrastructure XAML s’appuie sur les dernières fonctionnalités ajoutées aux moteurs multimédias UWP afin que les applications obtiennent ces améliorations gratuitement. Ici, nous expliquons quelques astuces supplémentaires qui vous permettent de tirer le meilleur parti des médias dans votre application UWP.
Publier des flux multimédias
Les fichiers multimédias sont parmi les ressources les plus courantes et coûteuses généralement utilisées par les applications. Étant donné que les ressources de fichiers multimédias peuvent augmenter considérablement la taille de l’empreinte mémoire de votre application, vous devez vous rappeler de libérer le descripteur des médias dès que votre application a terminé son utilisation.
Par exemple, si votre application fonctionne avec un objet RandomAccessStream ou IInputStream , veillez à appeler la méthode close sur l’objet lorsque votre application a terminé de l’utiliser, pour libérer l’objet sous-jacent.
Afficher la lecture vidéo en plein écran lorsque cela est possible
Dans les applications UWP, utilisez toujours la propriété IsFullWindow sur MediaPlayerElement pour activer et désactiver le rendu de fenêtre complète. Cela garantit que les optimisations au niveau du système sont utilisées lors de la lecture multimédia.
L’infrastructure XAML peut optimiser l’affichage du contenu vidéo lorsqu’il s’agit de la seule chose rendue, ce qui entraîne une expérience qui utilise moins de puissance et génère des taux d’images plus élevés. Pour la lecture multimédia la plus efficace, définissez la taille d’un MediaPlayerElement sur la largeur et la hauteur de l’écran et n’affichez pas d’autres éléments XAML
Il existe des raisons légitimes de superposer des éléments XAML sur un MediaPlayerElement qui occupe la largeur et la hauteur complètes de l’écran, par exemple des légendes fermées ou des contrôles de transport momentané. Veillez à masquer ces éléments (définis Visibility="Collapsed"
) lorsqu’ils ne sont pas nécessaires pour remettre la lecture multimédia dans son état le plus efficace.
Afficher la désactivation et la conservation de l’alimentation
Pour empêcher la désactivation de l’affichage lorsque l’action de l’utilisateur n’est plus détectée, par exemple lorsqu’une application joue une vidéo, vous pouvez appeler DisplayRequest.RequestActive.
Pour conserver l’alimentation et la durée de vie de la batterie, vous devez appeler DisplayRequest.RequestRelease pour libérer la demande d’affichage dès qu’elle n’est plus nécessaire.
Voici quelques situations où vous devez libérer la demande d’affichage :
- La lecture vidéo est suspendue, par exemple par action utilisateur, mise en mémoire tampon ou ajustement en raison d’une bande passante limitée.
- La lecture s’arrête. Par exemple, la vidéo est terminée ou la présentation est terminée.
- Une erreur de lecture s’est produite. Par exemple, les problèmes de connectivité réseau ou un fichier endommagé.
Placer d’autres éléments sur le côté de la vidéo incorporée
Souvent, les applications offrent une vue intégrée où la vidéo est diffusée dans une page. Maintenant, vous avez évidemment perdu l’optimisation en plein écran, car le MediaPlayerElement n'a pas la taille de la page et qu'il y a d'autres objets XAML dessinés. Attention à entrer involontairement dans ce mode en dessinant une bordure autour d’une MediaPlayerElement.
Ne dessinez pas d’éléments XAML au-dessus de la vidéo lorsqu’il est en mode incorporé. Si vous le faites, le cadre devra effectuer un peu de travail supplémentaire pour composer la scène. Placer des contrôles de transport sous un élément multimédia incorporé au lieu de les placer sur la vidéo est un bon exemple d’optimisation pour cette situation. Dans cette image, la barre rouge indique un ensemble de contrôles de transport (lecture, pause, arrêt, etc.).
Ne placez pas ces contrôles sur un média qui n’est pas plein écran. Au lieu de cela, placez les commandes de transport quelque part en dehors d'une zone où le média est affiché. Dans l’image suivante, les contrôles sont placés sous l'élément multimédia.
Retarder la définition de la source d’un MediaPlayerElement
Les moteurs multimédias sont des objets coûteux et l’infrastructure XAML retarde le chargement des dll et la création d’objets volumineux aussi longtemps que possible. Le MediaPlayerElement est forcé d’effectuer ce travail une fois sa source définie via la propriété Source. La définition de ce paramètre lorsque l’utilisateur est vraiment prêt à lire les médias retarde la majorité des coûts associés à MediaPlayerElement aussi longtemps que possible.
Définissez la propriété PosterSource de MediaPlayerElement
La définition de MediaPlayerElement.PosterSource permet au code XAML de libérer certaines ressources GPU qui auraient autrement été utilisées. Cette API permet à une application d’utiliser le moins de mémoire possible.
Améliorer le défilement multimédia
Le nettoyage est toujours une tâche difficile pour les plateformes multimédias afin de rendre vraiment réactif. En règle générale, les utilisateurs effectuent cette opération en modifiant la valeur d’un curseur. Voici quelques conseils sur la façon de rendre cela aussi efficace que possible :
- Mettez à jour la valeur de
en fonction d’un minuteur qui interroge l' positionCurseur sur le . Veillez à utiliser une fréquence de mise à jour raisonnable pour votre minuteur. La propriété Position met uniquement à jour toutes les 250 millisecondes pendant la lecture.MediaPlayerElement.MediaPlayer - L'intervalle de pas sur le curseur doit être ajusté en fonction de la longueur de la vidéo.
- Abonnez-vous aux événements PointerPressed, PointerMoved, PointerReleased sur le curseur pour définir la propriété PlaybackRate sur 0 lorsque l'utilisateur fait glisser la poignée du curseur.
- Dans le gestionnaire d’événements PointerReleased, définissez manuellement la position du média sur la valeur de position du curseur pour obtenir un alignement optimal du pouce lors du nettoyage.
Mettre en correspondance la résolution vidéo à la résolution d’appareil
La vidéo de décodage prend beaucoup de mémoire et de cycles GPU. Choisissez donc un format vidéo proche de la résolution à laquelle il sera affiché. Il est inutile d'utiliser les ressources pour décoder une vidéo en 1080p si elle va être réduite à une taille beaucoup plus petite. De nombreuses applications n’ont pas la même vidéo encodée à différentes résolutions ; mais s’il est disponible, utilisez un encodage proche de la résolution à laquelle il sera affiché.
Choisir les formats recommandés
La sélection de format multimédia peut être un sujet sensible et est souvent pilotée par les décisions d’entreprise. Du point de vue des performances UWP, nous recommandons la vidéo H.264 comme format vidéo principal et AAC et MP3 comme formats audio préférés. Pour la lecture de fichiers local, MP4 est le conteneur de fichiers préféré pour le contenu vidéo. Le décodage H.264 est accéléré via le matériel graphique le plus récent. En outre, bien que l’accélération matérielle pour le décodage VC-1 soit largement disponible, pour un grand ensemble de matériel graphique sur le marché, l’accélération est limitée dans de nombreux cas à un niveau d’accélération partielle (ou IDCT), plutôt qu’un déchargement matériel de niveau vapeur complet (c’est-à-dire le mode VLD).
Si vous avez un contrôle total du processus de génération de contenu vidéo, vous devez déterminer comment maintenir un bon équilibre entre l’efficacité de compression et la structure GOP. Une taille de GOP relativement plus petite avec des images B peut augmenter les performances en mode de recherche ou mode spécial.
Lorsque vous incluez des effets audio courts et à faible latence, par exemple dans les jeux, utilisez des fichiers WAV avec des données PCM non compressées pour réduire la surcharge de traitement typique des formats audio compressés.
Optimiser les ressources d’image
Mettre à l’échelle des images à la taille appropriée
Les images sont capturées à des résolutions très élevées, ce qui peut entraîner l’utilisation d’applications à l’aide d’un processeur supplémentaire lors du décodage des données d’image et de la mémoire après son chargement à partir du disque. Mais il n’y a aucun sens de décodage et d’enregistrement d’une image haute résolution en mémoire uniquement pour l’afficher plus petite que sa taille native. Au lieu de cela, créez une version de l’image à la taille exacte qu’elle sera dessinée à l’écran à l’aide des propriétés DecodePixelWidth et DecodePixelHeight .
Fais pas ça:
<Image Source="ms-appx:///Assets/highresCar.jpg"
Width="300" Height="200"/> <!-- BAD CODE DO NOT USE.-->
À la place, procédez comme suit :
<Image>
<Image.Source>
<BitmapImage UriSource="ms-appx:///Assets/highresCar.jpg"
DecodePixelWidth="300" DecodePixelHeight="200"/>
</Image.Source>
</Image>
Les unités de DecodePixelWidth et DecodePixelHeight sont par défaut des pixels physiques. La propriété DecodePixelType peut être utilisée pour modifier ce comportement : définir DecodePixelType sur logique entraîne la taille de décodage à automatiquement prendre en compte le paramètre d’échelle actuel du système, comme pour d'autres contenus XAML. Il serait donc généralement approprié de définir DecodePixelType sur Logique si, par exemple, vous souhaitez que DecodePixelWidth et DecodePixelHeight correspondent aux propriétés Height et Width du contrôle Image dans lequel l’image sera affichée. Avec le comportement par défaut de l’utilisation de pixels physiques, vous devez tenir compte du facteur d’échelle actuel du système vous-même ; et vous devez écouter les notifications de modification de mise à l’échelle si l’utilisateur modifie ses préférences d’affichage.
Si DecodePixelWidth/Height sont explicitement définis plus grand que l’image s’affiche à l’écran, l’application utilisera inutilement de la mémoire supplémentaire (jusqu’à 4 octets par pixel), ce qui devient rapidement coûteux pour les grandes images. L'image sera également réduite à l'aide d'une mise à l'échelle bilinéaire, ce qui pourrait la rendre floue pour les grands facteurs d'échelle.
Si DecodePixelWidth/DecodePixelHeight sont explicitement définis plus petits que la taille à laquelle l'image sera affichée à l'écran, elle sera agrandie et pourrait apparaître pixelisée.
Dans certains cas où une taille de décodage appropriée ne peut pas être déterminée à l’avance, vous devez différer le décodage automatique de taille droite de XAML, ce qui fera le meilleur effort pour décoder l’image à la taille appropriée si un décodage explicite DecodePixelWidth/DecodePixelHeight n’est pas spécifié.
Vous devez définir une taille de décodage explicite si vous connaissez la taille du contenu de l’image à l’avance. Vous devez également définir conjointement DecodePixelType sur logique si la taille de décodage fournie est relative à d’autres tailles d’éléments XAML. Par exemple, si vous définissez explicitement la taille du contenu avec Image.Width et Image.Height, vous pouvez définir DecodePixelType sur DecodePixelType.Logical pour utiliser les mêmes dimensions de pixel logique qu’un contrôle Image, puis utiliser explicitement BitmapImage.DecodePixelWidth et/ou BitmapImage.DecodePixelHeight pour contrôler la taille de l’image afin d’obtenir des économies de mémoire potentiellement importantes.
Notez que Image.Stretch doit être pris en compte lors de la détermination de la taille du contenu décodé.
Décodage adapté
Dans le cas où vous ne définissez pas de taille de décodage explicite, XAML tentera d’économiser de la mémoire en décodant une image à la taille exacte qu’elle apparaîtra à l’écran en fonction de la disposition initiale de la page contenante. Vous êtes invité à écrire votre application de manière à utiliser cette fonctionnalité si possible. Cette fonctionnalité est désactivée si l’une des conditions suivantes est remplie.
- Le BitmapImage
est connecté à l’arborescence XAML dynamique après avoir défini le contenu avec SetSourceAsync ou .UriSource - L’image est décodée à l’aide du décodage synchrone tel que SetSource.
- L'image est masquée via le paramètre opacité sur zéro ou visibilité sur réduit à sur l'élément d'image hôte, le pinceau ou tout élément parent.
- Le contrôle d’image ou le pinceau utilise un Stretch de None.
- L’image est utilisée en tant que NineGrid.
-
CacheMode="BitmapCache"
est défini sur l’élément image ou sur n’importe quel élément parent. - Le pinceau d’image n’est pas rectangulaire (par exemple, lorsqu’il est appliqué à une forme ou à un texte).
Dans les scénarios ci-dessus, la définition d’une taille de décodage explicite est la seule façon d’économiser de la mémoire.
Vous devez toujours attacher une BitmapImage à l’arborescence dynamique avant de définir la source. Chaque fois qu’un élément d’image ou un pinceau est spécifié dans le balisage, ce sera automatiquement le cas. Les exemples sont fournis ci-dessous sous le titre « Exemples d’arborescences dynamiques ». Vous devez toujours éviter d’utiliser SetSource et utiliser Plutôt SetSourceAsync lors de la définition d’une source de flux. Et il est judicieux d’éviter de masquer le contenu de l’image (avec zéro opacité ou avec une visibilité réduite) en attendant que l’événement ImageOpened soit déclenché. Il s'agit d'une décision basée sur le jugement : vous ne bénéficierez pas du décodage automatique de taille appropriée si cela est fait. Si votre application doit masquer le contenu de l’image initialement, elle doit également définir la taille de décodage explicitement si possible.
exemples d’arborescences dynamiques
Exemple 1 (bon) : URI (Uniform Resource Identifier) spécifié dans le balisage.
<Image x:Name="myImage" UriSource="Assets/cool-image.png"/>
Exemple de balisage 2 : URI spécifié dans le code-behind.
<Image x:Name="myImage"/>
Exemple 2 code-behind (bon) : connexion de l'objet BitmapImage à l'arbre avant de définir son UriSource.
var bitmapImage = new BitmapImage();
myImage.Source = bitmapImage;
bitmapImage.UriSource = new URI("ms-appx:///Assets/cool-image.png", UriKind.RelativeOrAbsolute);
Exemple 2 code-behind (incorrect) : définition de l’UriSource de BitmapImage avant de la connecter à l’arborescence.
var bitmapImage = new BitmapImage();
bitmapImage.UriSource = new URI("ms-appx:///Assets/cool-image.png", UriKind.RelativeOrAbsolute);
myImage.Source = bitmapImage;
Optimisations de la mise en cache
Les optimisations de mise en cache sont appliquées aux images qui utilisent UriSource pour charger du contenu à partir d’un package d’application ou du web. L’URI est utilisé pour identifier de manière unique le contenu sous-jacent et, en interne, l’infrastructure XAML ne télécharge pas ou ne décodera pas le contenu plusieurs fois. Au lieu de cela, il utilisera les ressources logicielles ou matérielles mises en cache pour afficher le contenu plusieurs fois.
L’exception à cette optimisation est le cas lorsque l’image est affichée plusieurs fois à différentes résolutions (qui peuvent être spécifiées explicitement ou par le biais d’un décodage automatique ajusté à la bonne taille). Chaque entrée de cache stocke également la résolution de l’image, et si XAML ne trouve pas une image avec un URI source qui correspond à la résolution requise, il décode une nouvelle version à cette taille. Toutefois, elle ne télécharge pas à nouveau les données d’image encodées.
Par conséquent, vous devez utiliser UriSource lors du chargement d’images à partir d’un package d’application, et éviter d’utiliser un flux de fichiers et SetSourceAsync lorsqu’il n’est pas nécessaire.
Images dans des panneaux virtualisés (ListView, par exemple)
Si une image est supprimée de l’arborescence, car l’application l’a explicitement supprimée, ou parce qu’elle se trouve dans un panneau virtualisé moderne et a été implicitement supprimée lors du défilement hors vue, XAML optimise l’utilisation de la mémoire en libérant les ressources matérielles de l’image, car elles ne sont plus nécessaires. La mémoire n’est pas libérée immédiatement, mais plutôt lors de la mise à jour de la trame qui se produit une seconde après que l'élément image ne soit plus dans l'arborescence.
Par conséquent, vous devez vous efforcer d’utiliser des panneaux virtualisés modernes pour héberger des listes de contenu d’image.
Images rasterisées par logiciel
Lorsqu’une image est utilisée pour un pinceau non rectangulaire ou pour un NineGrid, l’image utilise un chemin de rastérisation logicielle, qui ne met pas à l’échelle les images du tout. En outre, il doit stocker une copie de l’image dans la mémoire logicielle et matérielle. Par exemple, si une image est utilisée comme pinceau pour un ellipse, l’image complète potentiellement volumineuse est stockée deux fois en interne. Lorsque vous utilisez NineGrid ou un pinceau non rectangulaire, votre application doit pré-mettre à l’échelle ses images à la taille approximative à laquelle elles seront affichées.
Chargement de l’image du thread d’arrière-plan
XAML dispose d’une optimisation interne qui lui permet de décoder de manière asynchrone le contenu d’une image vers une surface en mémoire matérielle sans nécessiter une surface intermédiaire dans la mémoire logicielle. Cela réduit l’utilisation maximale de la mémoire et la latence de rendu. Cette fonctionnalité est désactivée si l’une des conditions suivantes est remplie.
- L’image est utilisée en tant que NineGrid.
-
CacheMode="BitmapCache"
est défini sur l’élément image ou sur n’importe quel élément parent. - Le pinceau d’image n’est pas rectangulaire (par exemple, lorsqu’il est appliqué à une forme ou à un texte).
SoftwareBitmapSource
Les SoftwareBitmapSource classe échangent des images non compressées interopérables entre différents espaces de noms WinRT tels que BitmapDecoder, les API de caméra et XAML. Cette classe supprime une copie supplémentaire qui serait généralement nécessaire avec WriteableBitmap, et qui permet de réduire la mémoire de pointe et la latence de la source à l'écran.
Le SoftwareBitmap qui fournit des informations sources peut également être configuré pour utiliser un IWICBitmap personnalisé pour fournir un stockage rechargeable qui permet à l’application de reconfigurer la mémoire selon ses besoins. Il s’agit d’un cas d’usage C++ avancé.
Votre application doit utiliser SoftwareBitmap et SoftwareBitmapSource pour interagir avec d’autres API WinRT qui produisent et consomment des images. Et votre application doit utiliser SoftwareBitmapSource lors du chargement de données d’image non compressées au lieu d’utiliser WriteableBitmap.
Utiliser GetThumbnailAsync pour les miniatures
Un cas d’usage pour la mise à l’échelle d’images consiste à créer des miniatures. Bien que vous puissiez utiliser DecodePixelWidth et DecodePixelHeight pour fournir de petites versions d’images, UWP fournit des API encore plus efficaces pour récupérer des miniatures. GetThumbnailAsync fournit les miniatures des images dont le système de fichiers est déjà mis en cache. Cela offre de meilleures performances que les API XAML, car l’image n’a pas besoin d’être ouverte ou décodée.
FileOpenPicker picker = new FileOpenPicker();
picker.FileTypeFilter.Add(".bmp");
picker.FileTypeFilter.Add(".jpg");
picker.FileTypeFilter.Add(".jpeg");
picker.FileTypeFilter.Add(".png");
picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
StorageFile file = await picker.PickSingleFileAsync();
StorageItemThumbnail fileThumbnail = await file.GetThumbnailAsync(ThumbnailMode.SingleItem, 64);
BitmapImage bmp = new BitmapImage();
bmp.SetSource(fileThumbnail);
Image img = new Image();
img.Source = bmp;
Dim picker As New FileOpenPicker()
picker.FileTypeFilter.Add(".bmp")
picker.FileTypeFilter.Add(".jpg")
picker.FileTypeFilter.Add(".jpeg")
picker.FileTypeFilter.Add(".png")
picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary
Dim file As StorageFile = Await picker.PickSingleFileAsync()
Dim fileThumbnail As StorageItemThumbnail = Await file.GetThumbnailAsync(ThumbnailMode.SingleItem, 64)
Dim bmp As New BitmapImage()
bmp.SetSource(fileThumbnail)
Dim img As New Image()
img.Source = bmp
Décoder des images une seule fois
Pour empêcher les images d’être décodées plusieurs fois, affectez la propriété Image.Source à partir d’un URI plutôt que d’utiliser des flux de mémoire. L’infrastructure XAML peut associer le même URI à plusieurs emplacements à une image décodée, mais elle ne peut pas faire de même pour plusieurs flux de mémoire qui contiennent les mêmes données et crée une image décodée différente pour chaque flux de mémoire.