Le WriteableBitmap avec Silverlight 3

Le WriteableBitmap est l’une des évolutions majeure de Silverlight 3.


Il permet de repousser les limites d’affichage de Silverlight, cantonné jusque là au vectoriel, en donnant au développeur la possibilité de travail au niveau du Pixel. Avant Silverlight 3.0 la génération à la volée d’images n’était pas possible nativement. Il fallait soit télécharger l’image générée depuis un serveur soit créer son propre générateur/encodeur. Avec WriteableBitmap (qui hérite de BitmapSource) la génération d’images à partir d’algorithmes, de contrôles ou d’instruction est réellement un jeu d’enfant.


Génération à partir d’un contrôle


Quelques règles à prendre en compte :


  • Le contrôle doit avoir une taille supérieure à new Size(0,0) evidemment.
  • Le contrôle doit appartenir à l’arborescence visuelle.
  • Le contrôle doit être visible.

Le constructeur de la classe WriteableBitmap permet de charger un contrôle sous la forme d’une image en une instruction :


Image image = new Image();//le controle chager
BitmapImage source = new BitmapImage();
source.UriSource = new Uri(“./Images/tunnelstonetex.png”, UriKind.Relative);
image.Source = source;
this.LayoutRoot.Children.Add(image);
this.texture = new WriteableBitmap(image, null);//on charge le rendu de la texture dans la WriteableBitmap


 Le second paramètre du contructeur WriteableBitmap permet de spécifier une transformation à appliquer au rendu de l’objet avant sa “rasterisation” en image.  WriteableBitmap possède une méthode nommée Render qui réalise le même travail. Il est en effet possible de créer aussi une image vide en spécifiant simplement la largeur et la hauteur de l’image  à créer afin de réaliser un rendu ultérieurement :


this.generatedTexture = new WriteableBitmap(400, 300);


 Modification dynamique


 Pour montrer la puissance de cette classe nous allons réaliser un rendu visuel dynamique basé sur l’effet du tunnel si cher à Vandevenne. Le but sera, au travers d’un dispatcher de modifier le contenu d’une texture à la volée à partir de valeur extraites d’un algorithme. Cette texture sera alors appliquée au background de notre contrôle root à l’aide d’un brush.


 Lorsque la WritableBitmap est créée, l’accès aux pixels de l’image se fait simplement au travers du membre Pixels (array de type int). Attention à bien noter que l’encodage des pixels de l’image se fait en BGRA. L’accès aux différentes composantes d’une couleur ainsi codée se fait simplement au travers de ce type d’instructions :


byte B = (byte)(pixel & 0xFF); pixel >>= 8;
byte G = (byte)(pixel & 0xFF); pixel >>= 8;
byte R = (byte)(pixel & 0xFF); pixel >>= 8;
byte A = (byte)(pixel);


Les membres PixelWidth et PixelHeight donnent respectivement la largeur et la hauteur de la WriteableBitmap. En gros l’array Pixel est de taille PixelWidth*PixelHeight. Mais attention à ne surtout pas utiliser ces membres dans une phase de génération de texture, c’est à dire une phase où les performances doivent être optimales. L’accès à l’accesseur de ces deux propriétés est extremement lent (DepepdencyProperty et instructions itératives ne font pas bon ménage). On ciblera un pixel particulier sur l’image à générer de cette manière :


this.generatedTexture.Pixels[x + y * generatedTextureWidth] = color;


Dans cette instruction x et y représentent les “coordonnées” du pixel à cibler dans la texture. Pixels était un array à une dimension nous multiplions y par la largeur de la texture (le Stride). La valeur color est un entier qui représente la couleur à appliquer en (x,y).


Voilà c’est à peu près tout ce qu’il y’a à savoir su WriteableBitmap. Peut on imaginer plus simple ? Cet article s’accompagne d’un sample téléchargeable ici. Si vous le lancez vous obtenez la sortie suivante :




Utilisation


Les contextes d’utilisation de la WriteableBitmap sont multiples. Pour les jeux vidéos elle offre l’opportunité de pouvoir travailler comme nous l’avons dit au niveau du pixel a la manière de shaders :


 
Oui, je suis un grand fan de Might and Magic :)


Pour des outils professionnels elle offre de nombreuses possibilités comme par exemple une zoombox :


 
Un controle que je vendais en indépendant et que j’ai pu refaire à la sauce Silvelight grâce à WriteableBitmap


Ou encore de pouvoir simplement et efficacement réaliser des effets graphiques comme le montre le sample de cet article.


[soon]


Valentin Billotte


 

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>