Windows Phone – Signature capturing with InkPresenter and save to PNG file

Today I received a small package by post for my neighbor and I must sign on a small device to confirm that I received the package. Therefore the deliver can be sure that I will give it to my neighbor. I thought it was very interesting to write a small application on Windows Phone which should work like the device of postman. This application allows people signing on the screen and it will store this signature into IsolatedStorageFile and show it again in image control below to confirm that the program works correctly.

As you can see in the demo image of application, I have 4 buttons: Undo, Redo, Clear and Save. The “Undo”, “Redo” buttons allow me to remove the strokes or redraw them. The strokes will be drawn on InkPresenter control and then saved into a PNG file. To draw the stroke on InkPresenter, I must handle the MouseLeftButtonDown to capture the mouse movement and draw stroke from point to point.

private StylusPoint GetStylusPoint(Point p)
{
	return new StylusPoint(p.X, p.Y);
}
private void inkSignature_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
	inkSignature.CaptureMouse();
	m_strokeCurrent = new Stroke();
	m_strokeCurrent.StylusPoints.Add(GetStylusPoint(e.GetPosition(inkSignature)));
	m_strokeCurrent.DrawingAttributes.Color = Colors.Blue;
	inkSignature.Strokes.Add(m_strokeCurrent);
}
private void inkSignature_MouseMove(object sender, MouseEventArgs e)
{
	if (m_strokeCurrent != null)
		m_strokeCurrent.StylusPoints.Add(GetStylusPoint(e.GetPosition(inkSignature)));
}

To implement “Undo” and “Redo” feature, I use a stack of strokes to push/pop a stroke in history and then remove/add it on InkPresenter.

private void btnUndo_Click(object sender, RoutedEventArgs e)
{
	if (inkSignature.Strokes != null && inkSignature.Strokes.Count > 0)
	{
		m_stackRemovedStrokes.Push(inkSignature.Strokes.Last());
		inkSignature.Strokes.RemoveAt(inkSignature.Strokes.Count - 1);
	}
}

private void btnRedo_Click(object sender, RoutedEventArgs e)
{
	if (m_stackRemovedStrokes != null && m_stackRemovedStrokes.Count > 0)
	{
		inkSignature.Strokes.Add(m_stackRemovedStrokes.Pop());
	}
}

At last, I use WriteableBitmap to take a snapshot of InkPresenter and encode it to a PNG format file. In current version of Visual Studio for Windows Phone CTP there is still not a PngBitmapEncoder. Therefore I use a custom one from this blog http://geekswithblogs.net/braulio/archive/2009/07/12/export-canvas-to-png-and-save-it-in-your-local.aspx . You can find the source code of PNG Encoder in the archive at the end of this post, too.

private void btnSave_Click(object sender, RoutedEventArgs e)
{
	WriteableBitmap wbBitmap = new WriteableBitmap(inkSignature, new TranslateTransform());
	EditableImage eiImage = new EditableImage(wbBitmap.PixelWidth, wbBitmap.PixelHeight);

	try
	{
		for (int y = 0; y < wbBitmap.PixelHeight; ++y)
		{
			for (int x = 0; x < wbBitmap.PixelWidth; ++x)
			{
				int pixel = wbBitmap.Pixels[wbBitmap.PixelWidth * y + x];
				eiImage.SetPixel(x, y,
				(byte)((pixel >> 16) & 0xFF),
				(byte)((pixel >>  8 ) & 0xFF ) ,
				(byte)(pixel & 0xFF), (byte)((pixel >> 24) & 0xFF)
				);
			}
		}
	}
	catch (System.Security.SecurityException)
	{
		throw new Exception("Cannot print images from other domains");
	}

	// Save it to disk
	Stream streamPNG = eiImage.GetStream();
	StreamReader srPNG = new StreamReader(streamPNG);
	byte[] baBinaryData = new Byte[streamPNG.Length];
	long bytesRead = streamPNG.Read(baBinaryData, 0, (int)streamPNG.Length);

	IsolatedStorageFileStream isfStream = new IsolatedStorageFileStream("temp.png", FileMode.Create, IsolatedStorageFile.GetUserStoreForApplication());
	isfStream.Write(baBinaryData, 0, baBinaryData.Length);
	isfStream.Close();

	//Show to image
	isfStream = new IsolatedStorageFileStream("temp.png", FileMode.Open, IsolatedStorageFile.GetUserStoreForApplication());
	BitmapImage biImage = new BitmapImage();
	biImage.SetSource(isfStream);
	isfStream.Close();
	imgResult.Source = biImage;
}

You can download complete source code here “Windows Phone Sig Capture
Reference: http://www.nickharris.net/2010/03/silverlight-for-mobile-on-windows-phone-7-inkpresenter-fun/

13 thoughts on “Windows Phone – Signature capturing with InkPresenter and save to PNG file”

  1. Thank you very much for this article!
    I have one question: does saved image has a transparent background?

  2. @Alexandr: In example above the saved image is the snapshot of control InkPresenter therefore the white area of image is the background of InkPresenter. So the saved image does not have a transparent background.

    If you would like to have a transparent background, try to set the background of InkPresenter to transparent and edit the code changes WriteableBitmap to EditableBitmap so that the alpha channel is set with opacity = 0.

  3. i wanted to download the “complete source code” and try it, but the archive-file only contains one file with no extension, when i open it width notepad, i cannot read (encrypted?). What do i have to do?

  4. @Sabrina Vill: Use Firefox to download or any download manager to download file. IE makes zip file corrupted.

  5. hi admin!

    Thank you for the tip, i downloaded it with firefox, that worked :-). Unfortunately i cannot open it, i use Visual Studio 2008, is this project made with 2010 version? How can i convert it to 2008?

  6. @Sabrina Vill: I am not sure that I used VS 2010 or VS 2008 with Add-in for developing Windows Phone Application for this project. Therefore create your own project then import the code only.

  7. Hi! Great article.

    Just one comment on the code. Why do you have the following line:

    StreamReader srPNG = new StreamReader(streamPNG)

    If srPNG is never used anywhere?

  8. I copy the code but i get the error at biImage.SetSource(isfStream);
    (it’s show “Unspecified error”).
    Can you help, please.

  9. Thanks for the code…I need one more step…How would you convert that png file to a byte array to save in a varbinary(max) field in a database? Any ideas?

  10. Hi @ *

    Thx for the code!! great!

    One more question.. can i change resolution (DPI) for this one? Right now i get a really big Image (about 1 MB for a sign).

    Thank you in advance

  11. hi ,

    i am using this code and creating application in silverligh3 but im not getting editableImage .It is showing dll or reference is not available. How to rectify this isssue.

    Thanks,
    sachin

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>