Announcement

All important changes of my site and my blog will be announced here.

Computer security

This is my hobby. I spend my freetime for it. I am not professional in this area. But I like it very much.

Everything Else

Which doesn’t belong to other categories will land here. It maybe about my daily life, entertainment, music, game … or something like that

Programming

This is my job. That means everyday I must sit before the monitor. Tip something, be annoyed by bugs,… but I simply like it.

Tutorial

When I found something interesting, I would like to share it to everyone. That is the reason for this category comes.

Home » Programming

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

Submitted by on Monday, 5 April 201012 Comments | 5,085 views

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/

Popularity: 7% [?]

My strongly recommended books to read. Choose one and enjoy yourself.

Related Posts:

  • No Related Posts

12 Comments »

  • Alexandr said:

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

  • admin (author) said:

    @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.

  • A Simple Paint App on Windows Phone 7 using InkPresenter « tried…. It worked….. :) said:
  • Sabrina Vill said:

    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?

  • admin (author) said:

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

  • Sabrina Vill said:

    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?

  • admin (author) said:

    @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.

  • Michael said:

    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?

  • piter said:

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

  • LA said:

    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?

  • Greg said:

    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

  • sachin prasad said:

    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 your response!

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

This is a Gravatar-enabled weblog. To get your own globally-recognized-avatar, please register at Gravatar.