1
2
3
4
5
6

Rendering Text to a WriteableBitmap with Silverlight 3's Bitmap API

One of the new features in Silverlight 3 (released on Friday) is the Bitmap API which provides the ability to render UIElements to a bitmap and provides direct access to the pixel level information of bitmaps. This type of functionality is very useful in a handful of situations, but perhaps the most notable is the ability to cache out a rendering of a UserControl and make use of it in complex transitions to reduce overhead, or to facilitate editing images or processing images through filters, etc.

I did a few searches tonight to get started playing with the Bitmap API and found several examples, but unfortunately none of them had any source code attached, and were written against previous SL3 betas which had different method signatures relevant to the bitmap rendering, so I wanted to go ahead and post a simple example of rendering out a UIElement to a bitmap. This example shows the output of rendering a TextBlock at various font sizes and image sizes and setting the resultant bitmaps as the source for three equal sized Image UIElements.

Get Microsoft Silverlight

(nothing exciting, at least for now)

In the attached code sample you'll see a method which creates a WriteableBitmap, and the resulting WriteableBitmap is set as the source for an Image UIElement. The code to render the bitmaps is very simple, the key (to not wasting your time) is to make sure that you always call Invalidate() on the WriteableBitmap before making use of it, otherwise you will never see anything in the created bitmaps. Here is the main rendering method:

(more after the break..)

   1:  private WriteableBitmap SetupRenderedTextBitmap(string text, double fontSize)
   2:  {
   3:      // setup the textblock we will render to a bitmap
   4:      TextBlock txt1 = new TextBlock();
   5:      txt1.Text = text;
   6:      txt1.FontSize = fontSize; // set the font size before using the Actual Width / Height
   7:   
   8:      // create our first bitmap we will render to
   9:      WriteableBitmap bitmap = new WriteableBitmap((int)txt1.ActualWidth, 
  10:          (int)txt1.ActualHeight);
  11:   
  12:      // put a black textblock under the white one to create a simple dropshadow
  13:      txt1.Foreground = new SolidColorBrush(Colors.Black);
  14:      bitmap.Render(txt1, new TranslateTransform() { X = -2, Y = -2 });
  15:   
  16:      txt1.Foreground = new SolidColorBrush(Colors.White);
  17:      bitmap.Render(txt1, new TranslateTransform());
  18:   
  19:      // invalidate the bitmap so that it is rendered
  20:      bitmap.Invalidate();
  21:   
  22:      return bitmap;
  23:  }

I'm hoping to take these basics of generating Bitmaps and use it in something a bit fancier next time, until then be sure to give it a whirl yourself and share what you're working on in Silverlight 3!

Update: I have used the text to bitmap abilities discussed in this post to make something a bit cooler, please check out the related post here!

AttachmentSize
BitmapAPIPlaytime.zip25.21 KB

Comments

hi,
im facing the similar kind of problem for richtextbox html content.
any suggestions ?


Thanks for showing the basics. I'm now trying to do a similar thing for my SL website and couldn't get UserControls loaded from xaml to render into WriteableBitmap before they passed the layout pass. Seems the TextBlock works well without!