Surface Multi-touch
As I mentioned in a previous post the Microsoft Surface implements multi-touch using infrared computer vision as opposed to a capacitive approach. This is interesting for a couple of reasons. First it allows the Surface to recognize a very large number of touches. Second, it allows ambitious developers to tap directly into this infrared image data to perform more complex operations (like shape recognition). Getting at this information however is not entirely straight forward though. To simply things I created an attached behavior.
Attached Behaviors
Attached behaviors are something that I’ve blogged about before. They are a very convenient way to add user interface behavior to controls without having to implement a proper subclass. This behavior also implements a custom attached event, which allows you to easily handle and process images captured from the Surface.
Using the Behavior
Using the behavior is simple; you just have to include the library in your solution, add the xmlns and set a couple of attached properties and an event handler:
<s:SurfaceWindow
behaviors:SurfaceWindowRawImageCapture.IsEnabled="True"
behaviors:SurfaceWindowRawImageCapture.RawImageCaptured="YourEventHandler">
(...)
</s:SurfaceWindow>
Optional Parameters
This behavior is designed to be flexible. There are several parameters that allow you to take advantage of this flexibility.
UseExplicitCapture=(true | false)
Setting this property to true will disable the attached event from being raised. It is false by default. Use it if you want to capture images programmatically which is explained below.
SaveTo=”C:\path\to\captured\images
Often it may be necessary to save the images that you capture to a specific location. If you set this property all images captured by the behavior will be saved to the specified directory.
Capturing Images Programmatically
The one drawback to the way that the Surface SDK allows developers to capture raw images is that the ContactDown event must be handled on the instance of the SurfaceWindow itself. What that means is that your attached event handler has to also be on the SurfaceWindow itself. The solution to this limitation is to call the behavior programmatically from your own code:
SurfaceWindowRawImageCapture.CaptureRawImageAsync(
Application.Current.MainWindow as SurfaceWindow,
new Rect(100, 100, 100, 100),
result =>
{
// Code to execute when the result has been captured
});
The Rect that is passed to the method defines an area to crop the entire Surface image. This is useful if you are only interested in a small sub-area of the total Surface. The callback that is passed to the method will be executed after the image has been captured.
Let me know if you run into any issues with the behavior by emailing me: charlie [you know] robbins [obviously] gmail [you know] com. As always, all of this code is available under the MIT license on GitHub.
