How To: Implement an Ink enabled Silverlight Photo Annotation Webpage

Now that Ink support in Silverlight 1.0 Beta is live, I thought I’d take an opportunity to walk you through a basic implementation of a web page with an inking surface that’s displayed over a photo. The approach is to start in xaml with a root Canvas, then add Image and InkPresenter elements as children of the root Canvas. This results in an image being displayed, with an InkPresenter overlaying that image. Next, we hook up mouse events in JavaScript to collect and display Ink over the image.

 

So let’s take a look at what code needs to be written to implement basic photo annotation:

 

XAML:

<Canvas xmlns="https://schemas.microsoft.com/client/2007"

    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"

    Loaded="javascript:root_Loaded"

    x:Name="root"

    Width="800" Height="533"

    Background="black">

  <Image Source="lake.jpg"/>

  <InkPresenter

    x:Name="inkPresenterElement"

    Background="transparent"

    Width="800" Height="533"

    MouseLeftButtonDown="javascript:InkPresenterMouseDown"

    MouseMove="javascript:InkPresenterMouseMove"

    MouseLeftButtonUp="javascript:InkPresenterMouseUp"/>

</Canvas>

 

In this xaml, we have our root Canvas “root”, our Image, then our InkPresenter “inkPresenterElement” that specifies mouse event handlers for down, move, and up.

 

JavaScript:

var silverlight;

var inkPresenter; // Corresponds to InkPresenter element in xaml

var newStroke = null; // The Stroke variable we’ll use here in mouse handlers

function root_Loaded(sender, args)

{

    silverlight = document.getElementById("agControl1");

    inkPresenter = sender.findname("inkPresenterElement");

}

// Capture mouse and create the stroke

function InkPresenterMouseDown(sender,args)

{

   inkPresenter.CaptureMouse();

   newStroke = silverlight.content.createFromXaml('<Stroke/>');

   newStroke.StylusPoints.AddStylusPoints(args.GetStylusPoints(inkPresenter));

   newStroke.DrawingAttributes.Color = "white";

   newStroke.DrawingAttributes.OutlineColor = "black";

   newStroke.DrawingAttributes.Width = 6;

   newStroke.DrawingAttributes.Height = 6;

   inkPresenter.Strokes.Add(newStroke);

}

// Add the new points to the Stroke we’re working with

function InkPresenterMouseMove(sender,args)

{

   if (newStroke != null)

   {

      newStroke.StylusPoints.AddStylusPoints(args.GetStylusPoints(inkPresenter));

   }

}

// Release the mouse

function InkPresenterMouseUp(sender,args)

{

   newStroke = null;

}

 

In this JavaScript, we have 4 methods:

root_Loaded: In this method, we initialize our variables that reference the Silverlight control, and the InkPresenter that we’ll be manipulating.

 

InkPresenterMouseDown: In this method, we capture the mouse (so we get events if we go outside the control), Initialize our Stroke variable with a newly created stroke, add the collected StylusPoints to the Stroke, set the DrawingAttibute properties on the Stroke, then add the Stroke to the InkPresenter. This causes it to be rendered over the photo.

 

InkPresenterMouseMove: In this method, we add collected StylusPoints to the current Stroke variable (if we’re collecting ink).

 

InkPresenterMouseUp: In this method we stop inking our stroke by nulling our Stroke variable.

 

So that’s all you really need to implement Ink photo annotation in with Silverlight! Later, I’ll post a more comprehensive example, but this will get you started…

 

Screenshot of photo annotation page in action:

 

If you want to play with the sample code for this example, just download the attachment.

 

Until next time, happy coding!

-Gavin

basic_silverlight_photo_anno.zip