Microsoft PixelSensepixelsense.com
Samsung SUR40 with Microsoft PixelSensesamsunglfd.com/solution/sur40.do
One common question I hear is: How can you consume the raw image provided by the core APIs in a WPF application? How do you display it on the screen?
I just extracted it from the code I used to “process the image” created by the cup on the monster demo.
Here is a simple answer to that question, the code is “AS IS” – use at your own risk.
Follow these steps:
1. Add the Microsoft.Surface.Core assembly to your project so you can reference it.
2. After your SurfaceWindow is initialized, do the necessary setup so that you can start receiving Raw Image events and data.
// Copyright © Microsoft Corporation. All Rights Reserved.
// This code released under the terms of the
// Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.)
/// <summary>
/// Default constructor.
/// </summary>
public SurfaceWindow1()
{
InitializeComponent();
SourceInitialized += new EventHandler(InitializeCore);
// Add handlers for Application activation events
AddActivationHandlers();
}
void InitializeCore(object sender, EventArgs e)
// Create a target for surface input, and start
// receiving normalized raw images.
contactTarget = new ContactTarget( new WindowInteropHelper(this).Handle, EventThreadChoice.OnCurrentThread);
// See step 3 for definition of OnContactTargetFrameReceived.
contactTarget.FrameReceived += OnContactTargetFrameReceived;
contactTarget.EnableInput();
contactTarget.EnableImage(ImageType.Normalized);
3. Now that you are receiving the raw image, do something with it. I my case I write it to a WriteableBitmap so that I can use it as a source to an Image in my visual tree. I write to the bitmap every 100 milliseconds.
// Assuming the following members of the class
private byte[] normalizedImage;
private ImageMetrics normalizedImageMetrics;
private static WriteableBitmap writeableBitmap;
// remembers the last time we showed the raw image.
private long oldTimeStamp;
/// Handler for the FrameReceived event. Here we get the
/// rawimage data from FrameReceivedEventArgs object.
/// <param name="sender">ContactTarget that received
/// the frame</param>
/// <param name="e">Object containing information about
/// the current frame</param>
private void OnContactTargetFrameReceived(
object sender,
FrameReceivedEventArgs e)
long now = DateTime.Now.Ticks;
lock (this)
long ticksDelta = Math.Abs(now - oldTimeStamp);
// Update image every 100 milliseconds.
if (ticksDelta > 100 * 10000)
int paddingLeft, paddingRight;
Rect imageBound = new Rect();
imageBound.X = 0;
imageBound.Y = 0;
imageBound.Width = 1024;
imageBound.Height = 768;
if (e.TryGetRawImage(
ImageType.Normalized,
(int)imageBound.Left,
(int)imageBound.Top,
(int)imageBound.Width,
(int)imageBound.Height,
out normalizedImage,
out normalizedImageMetrics,
out paddingLeft,
out paddingRight))
WriteToImage(normalizedImage, normalizedImageMetrics);
imageToShow.Source = writeableBitmap;
oldTimeStamp = now;
/// The WriteToImage method updates the
/// WriteableBitmap by using unsafe code to write
/// a pixel into the back buffer.
/// <param name="normalizedImage">The raw image</param>
/// <param name="metrics">The size of the raw image</param>
static void WriteToImage(byte[] image, ImageMetrics metrics)
int maxRow = metrics.Height;
int maxCol = metrics.Width;
if (writeableBitmap == null)
writeableBitmap =
new WriteableBitmap(
maxCol,
maxRow,
96,
PixelFormats.Bgr32, null);
writeableBitmap.Lock();
unsafe
for (int y = 0; y < maxRow; y++)
for (int x = 0; x < maxCol; x++)
int color_data = 0;
int pBackBuffer = (int)writeableBitmap.BackBuffer;
pBackBuffer += y * writeableBitmap.BackBufferStride;
pBackBuffer += x * 4;
// Set Red, Green, Blue respectively
color_data = image[x + y * metrics.Stride] * 2 << 16;
color_data |= image[x + y * metrics.Stride] * 2 << 8;
color_data |= image[x + y * metrics.Stride] * 2 << 0;
*((int*)pBackBuffer) = color_data;
try
writeableBitmap.AddDirtyRect(new Int32Rect(0, 0, maxCol, maxRow));
catch (Exception ex)
string s = ex.ToString();
finally
writeableBitmap.Unlock();
That was it! I hope this is helpful. Let me know if you have questions.
Luis CabreraPlatform Program Manager
Microsoft Surface