Convert WPF InkCanvas to Bitmap


We live in a digital age and if you are like me, paper is only used when it is absolutely unavoidable. If you have a tablet PC, signing your name to attach it to a document may be one less thing you will need a physical sheet of paper for.

The WPF ink control can be put into your XAML to collect stylus strokes as a collection of geometry points. Of course, as the stylus moves, the movements are also shown on screen.

inktest

[more]

As I mentioned, the strokes shown in the control are actually stored as a collection of geometric lines. If you want to reproduce those ink strokes, you can save the collection found in a property on the control called "Strokes", but what you can't do with the control's data is store a rendered image of it. Or, at least you can't do this without a little extra work.

One of the nice things about WPF is that its controls can actually be rendered into an image with relative ease. I submit the following code snipit as my solution for rendering the contents of an InkCanvas to a bitmap image:

XAML:

<StackPanel Name="spHorizontal" Orientation="Horizontal">
   <InkCanvas Name="icSignature" MinWidth="575" MinHeight="100" />
</StackPanel>

 

C#:

private byte[] SignatureToBitmapBytes()
{   
   //get the dimensions of the ink control
   int margin = (int)this.icSignature.Margin.Left;
   int width = (int)this.icSignature.ActualWidth - margin;
   int height = (int)this.icSignature.ActualHeight - margin;

   //render ink to bitmap
   RenderTargetBitmap rtb =
      new RenderTargetBitmap(width, height, 96d, 96d, PixelFormats.Default);
   rtb.Render(icSignature);

   //save the ink to a memory stream
   BmpBitmapEncoder encoder = new BmpBitmapEncoder();
   encoder.Frames.Add(BitmapFrame.Create(rtb));
   byte[] bitmapBytes;
   using (MemoryStream ms = new MemoryStream())
   {
      encoder.Save(ms);

      //get the bitmap bytes from the memory stream
      ms.Position = 0;
      bitmapBytes = ms.ToArray();
   }
   return bitmapBytes;
}

As you can see, the bytes of the bitmap are read back out of a memory stream (line 23), but it would also be just as easy to save directly to a file stream; bypassing the memory stream.

The WPF InkCanvas can be used for many, many things (annotating video and images is one cool example I've seen), but another use for it can be a do-it-yourself signature pad.