#Windows Apps : attention à votre carte graphique lorsque vous utilisez le RenderTargetBitmap
Petit article de blog sur une fonctionnalité sympathique du RenderTargetBitmap dans une application Windows. Le downscaling automatique pour s’adapter à votre machine.
Le RenderTargetBitmap est un composant très pratique car il permet de faire le rendu sous forme d’image d’un composant XAML.
Pour faire ce rendu, il utilise sous le capot une surface DirectX et cela provoque un comportement à connaitre : le rendu de l’image aura au maximum la taille maximum des surfaces DirectX supportées par la carte graphique de la machine ou est exécutée l’application. (4096 par exemple sur ma Surface Pro 3). Par contre, le ratio de l’image reste bien respecté (pas de soucis à se faire donc).
Cela n’a pas en général de conséquences graves mais cela peut provoquer un crash lorsque vous permettez à un utilisateur de faire un crop sur ce rendu : la taille de la sélection peut dépasser la taille de l’image rendu.
Pour détecter ce cas, il suffit finalement de calculer le ratio entre la taille voulue et la taille finalement rendue par le RenderTargetBitmap. Cette dernière information étant retournée par la propriété PixelWidth du RenderTargetBitmap après le rendu.
//Rendu de l'élément await renderTargetBitmap .RenderAsync(elementDontJeVeuxLeRendu, elementWidth, elementHeight); // récupération des pixels var pixels = await renderTargetBitmap.GetPixelsAsync(); // ratio de rendu - 1 normalement mais peut être changé par le rendu var finalRatioW = renderTargetBitmap.PixelWidth / elementDontJeVeuxLeRendu.ActualWidth; var finalRatioH = renderTargetBitmap.PixelHeight / elementDontJeVeuxLeRendu.ActualHeight; //Création de l'encoder d'image var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, target); // utilisation des ratios pour découper l'image encoder.BitmapTransform.Bounds = new BitmapBounds { X = 0, Y = 0, Width = (uint)( widthSelection* finalRatioW), Height = (uint)(heightSelection * finalRatioH ), }; //Utilisation de l'encoder encoder.SetPixelData( BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)renderTargetBitmap.PixelWidth, (uint)renderTargetBitmap.PixelHeight, 96, 96, bytes); // Avant cela crashait ici await encoder.FlushAsync();
La documentation MSDN est bien à jour : https://msdn.microsoft.com/fr-fr/library/windows/apps/dn298557
Bon dev !
PS: oui j’ai résisté à faire la blague évidente sur ce genre de problème :)
![Photo de profil](https://infiniteblogs.blob.core.windows.net/medias/825f7ae4-d509-474a-8763-29ec15ab67cb_6c35b7d0-49c7-4a61-ba48-5e29b085bfcc_outlook.jpg)
Commentaires