Derik Whittaker

Syndication

News


How to Capture User Signatures on WP7

Since the iPhone came out a few years ago the idea of using a stylus on a cell phone to perform any type of input action as become ‘old school’.  Steve Jobs once said that if your phone uses a stylus you are doing it wrong (which by the way if I remember he was taking direct aim at Windows Phone 6.5… and rightfully so). 

As much as I agree that you should be able to interact with a phone with simply your fingers a stylus has one advantage in ONE area, signature input capture (or simply drawing).  Of course you can use your finger to draw/create a signature but a stylus simply makes it easier as we are more accustom to using a pen not our fingers for these things.  In this post I will walk though how we can capture user drawing/signature input on the WP7 platform and turn this input into a signature.

 

Step 1 – How to capture the signature

  1. Create a Canvas Control and place it on your form
  2. Hookup the following 3 events on the canvas
    1. ManipulationStarted
    2. ManipulationCompleted
    3. ManipulationDelta
  3. Create the logic to handle the 3 events we just registered
    1. Pre-Event Setup Code
      	private Polyline _lineBeingDrawn;
      	private IList<ilist<point>> _points = new List<ilist<point>>();
      	
    2. ManipulationStarted
      // Here we want to start our new line for drawing and we want to 
      // add the polyline as a child item to the SignatureCanvas.
      _lineBeingDrawn = new Polyline
      	{
      	        Stroke = new SolidColorBrush(Colors.Orange),
              	StrokeThickness = SignatureStrokeThickness,
              	Points = new PointCollection { new Point(e.ManipulationOrigin.X, e.ManipulationOrigin.Y) }
      	};
      
      
      SignatureCanvas.Children.Add(_lineBeingDrawn);
    3. ManipulationCompleted
      // Here we want to simply add the points information to the list of points we
      // are capturing in order to redraw this later if needed.
      _points.Add(_lineBeingDrawn.Points);
    4. ManipulationDelta
      // Here we are adding new points to the PolyLine we created and added as a child 
      // in the Started event above
      _lineBeingDrawn.Points.Add(new Point(e.ManipulationOrigin.X, e.ManipulationOrigin.Y));


Step 2 – How to redraw the signature on the screen
After we hooked up the events above we should be able to not only draw on the canvas but we should also be storing the points for each movement into our _points collection.  Given this fact we can redraw the image on a clean canvas with very little effort. The code below will show how to redraw the signature.

// We want to loop through the list of points we have been creating.  With each outer element in the list
// we create a new Polyline and then loop though each segment of that point.
// When we are done with the segments we simply add the PolyLine to the canvas
foreach (var segment in _points)
{
    _lineBeingDrawn = new Polyline
    {
        Stroke = new SolidColorBrush(Colors.Brown),
        StrokeThickness = 3.00,
    };


    foreach (var point in segment)
    {
        _lineBeingDrawn.Points.Add(new Point(point.X, point.Y));
    }

    SignatureCanvas.Children.Add(_lineBeingDrawn);
}

 

Step 3 – How to create an image from the signature
Now that we have been able to capture the signature and redraw it how do we save the information to a bitmap?  Well this is a bit more work (and this code is courtesy of one of my awesome XAML developers on my mobile team so I take NO credit, just blame for this) but is not all the hard.

var group = new GeometryGroup();
Path path = new Path()
                {
                    Stroke = new SolidColorBrush(Colors.Black),
                    StrokeThickness = SignatureStrokeThickness,
                    Data = group
                };

foreach (var segment in _points)
{
    Point? startPoint = new Point?();
    for (int pIndex = 0; pIndex < segment.Count; pIndex++)
    {
        var point = segment[pIndex];
        if (pIndex == 0)
        {
            startPoint = point;
        }
        else if (startPoint != null)
        {
            var geometry = new LineGeometry
                                {
                                    StartPoint = startPoint.Value,
                                    EndPoint = point
                                };
            group.Children.Add(geometry);
            startPoint = point;
        }
    }
}

path.Measure(SignatureCanvas.DesiredSize);
path.Arrange(new Rect(new Point(), path.DesiredSize));

//fill white background
{
    Path backgroundPath = new Path()
                                {
                                    Fill = new SolidColorBrush(Colors.White),
                                    Data = new RectangleGeometry()
                                                {
                                                    Rect =
                                                        new Rect(0, 0, bitmap.PixelWidth,
                                                                bitmap.PixelHeight)
                                                }
                                };
    bitmap.Render(backgroundPath, null);
}

bitmap.Render(path, null);
bitmap.Invalidate();

//convert to binnary array
MemoryStream imgStream = new MemoryStream();
bitmap.SaveJpeg(imgStream, bitmap.PixelWidth, bitmap.PixelHeight, 0, 100);
byte[] bitmapData = imgStream.ToArray();

As you can see creating the ability to not only capture signatures (or simply user input) and then converting the data into a bitmap is NOT hard but it does take a bit of effort. Hope this helps someone.

Till next time,


Posted 03-25-2011 5:41 AM by Derik Whittaker
Filed under: , , ,

[Advertisement]

Comments

asdads wrote re: How to Capture User Signatures on WP7
on 03-30-2011 4:26 PM

does not work. can you share sourcecode?

Biztalk Musings wrote Signature Pad in WP7
on 04-04-2011 4:30 PM

Signature Pad in WP7

Priyanka wrote re: How to Capture User Signatures on WP7
on 04-08-2011 6:44 AM

# private IList<ilist<point>> _points = new List<ilist<point>>();  

gives error....can u upload full source code??

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)