Capturing Signature on the Pocket PC

If you have ever received a package from one of the courier companies (FedEx, UPS or DHL). you have no doubt been asked to sign for the package on a mobile computer that the courier carries with him. How do you do that on the Pocket PC? In the sample below, you will use GDI+ to draw lines that make up a user’s signature and then store them in series of coordinates.

First, Inherits signature class from control and declare its member variables as below:

public class signature : Control

As the user uses the stylus to write on the control, the series of points it made on the control will be saved. There will be three events of concern to us in the sequence:

  • onMouseDown – this event is fired when the stylus touches on the control
  • onMouseMove – this event is fired when the stylus is dragged on the control
  • onMouseUp – this event is fired the stylus in lifted from the control

When the user tabs on the screen, it will fires event handler:

if (_Enable == true)
{
_previouspoint.X = e.X;
_previouspoint.Y = e.Y;


_points = new ArrayList();
_points.Add(_previouspoint);
}

When the user drags his stylus, it will fires OnMouseMove event handler:

if (_Enable == true)
{
_points.Add(new Point(e.X, e.Y));
_g.DrawLine(_pen, _previouspoint.X, _previouspoint.Y,
e.X, e.Y);
_previouspoint.X = e.X;
_previouspoint.Y = e.Y;
Invalidate();
}

When the user lifts his stylus, it will fires OnMouseUp event handler:

if (_Enable == true)
{
Int32 _count = _points.Count - 1;
Point[] pts = new Point[_count];
for (int i = 0; i < _points.Count - 1; i++)
{
pts[i] = (Point)_points[i];
}
_lines.Add(pts);
}

After that, add InitSignature(string bmpLocation) methods to load the background image for the control with image location as parameter.

String path = bmpLocation;
_bmp = new Bitmap(path);
_picHeight = _bmp.Height;
_picWidth = _bmp.Width;
_g = Graphics.FromImage(_bmp);
Invalidate();

Now you need to override the OnPaint() event handler so that the display on the control will up-to-date.

e.Graphics.DrawImage(_bmp, 0, 0);

DrawSignature is needed when you load the contain of data from save location such as _lines ArrayList object:

for (int line = 0; line <= _lines.Count - 1; line++)
{
Point[] pts = (Point[])_lines[line];
for (int i = 1; i <= pts.Length - 1; i++)
{
_g.DrawLine(_pen, pts[i - 1].X, pts[i - 1].Y, pts[i].X, pts[i].Y);
}
}
Invalidate();

Lastly define the Signature property so that users can either obtain the value of the signature or set it to display a signature:

get
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
foreach (Point[] ar in _lines)
{
foreach (Point pt in ar)
{
sb.Append(pt.X.ToString() + "," + pt.Y.ToString() + "|");
}
sb.Append("@");
}
return sb.ToString();
}
set
{
_lines.Clear();
Char[] valueDeliminator = { '@' };
Char[] lineDeliminator = { '|' };
Char[] pointDeliminator = { ',' };
string[] lines = value.Split(valueDeliminator);


for (int i = 0; i <= lines.Length - 2; i++)
{
string[] ps = lines[i].Split(lineDeliminator);
Point[] points = new Point[ps.Length - 2];
for (int j = 0; j < ps.Length - 2; j++)
{
string[] xy = ps[j].Split(pointDeliminator);
points[j] = new Point(Convert.ToInt32(xy[0]), Convert.ToInt32(xy[1]));
}
_lines.Add(points);
}
DrawSignature();
}

Now you can use it to integrate with you program. Hope this will help you.

Download Script

1 Comment

  • szehau

    October 12, 2007 at 12:03 pm

    I would suggest some optimization over your code

    – Constructor
    Create a fix size array, say “bool pix[MAX_WIDTH*MAX_HEIGHT];”, that represent the state of all the pixels on the screen.

    – OnMouseMove
    Set the state of that (x,y) pixel, say “pix[x+y*MAX_WIDTH] = true;”
    Refresh screen (Invalidate)

    – To export the signature map to visible string
    foreach pix[xi+yi*MAX_WIDTH] that is true, append to string as value of (xi+yi*MAX_WIDTH) and also separate with any separator (e.g. “,)

    – To import visible string and convert into signature map
    Reset the pix array (set all element to false). Read string and throw away the separators, convert the value into integer. Set “pix[value] = true”. Make sure validate the value to avoid buffer over/underflow

    – Draw the signature
    foreach pix[xi+yi*MAX_WIDTH] that is true, set the screen pixel to a color. if you want the signature looks “bold”er, u can draw a circle with larger radius around the pixel.

Post a Comment