Entries:
Comments:
Posts:

Loading User Information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading User Information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

Do You Like Me? Check This Box! Blogging with the Logitech io2 Digital Pen

  Interfacing Logitech io2 Digital Pen using .Net. Application allows to write up a blog post using the digital pen and paper, dock the pen, then from the Logitech organizer software select a menu my plug-in will and the digital ink would be transferred to the blog.
Scott Hanselman's Computer Zen

Difficulty: Intermediate
Time Required: 6-10 hours
Cost: $100-$200
Software: Visual Studio Express Editions, Logitech io2 Software Plug-in Toolkit
Hardware:
Download:

The Logitech io2 Digital Pen

I sometimes jokingly call the Logitech io2 pen the "poor man's TabletPC." It's a digital pen that uses real ink. The magic is the tiny camera sensor next to the ink tip that reads the absolute position of the pen on specially printed paper. The technology is licensed by Logitech from Anoto. Here's the details from Anoto's own web site:

"The Anoto pattern consists of small dots with a nominal spacing of 0.3 mm (0.01 inch). These dots are slightly displaced from a grid structure to form the proprietary Anoto pattern. When writing with a digital pen on a paper printed with the pattern, digital snapshots of the pattern are taken with a rate of more than 50 per second. Every snapshot contains enough information to make a calculation of the exact position of the pen. The intelligence in the paper, derived from the pattern, makes it possible to perform operations by just ticking a box with the pen, e.g. Store, Send, To Do, Address, etc."

To the naked eye the paper looks slightly off white. You don't even notice the dots. You write with the slightly oversized—but no overly so—pen on what looks like regular paper. You can buy the custom notebooks and Post-its for as little as $5 from Logitech directly or at office supply stores. I like the Black n' Red notebook, myself.

You can use their software to store and manipulate the digital ink files, save them as images, export to Word or OneNote, as well as run OCR (optical character recognition) on the pages.

Logitech's io2 Pen SDK

The pen by itself is a pretty slick gadget, but why does it deserve a Some Assembly Required article? Because it has a full and supported .NET-based SDK! The Logitech io2 Software Plug-in Toolkit (FAQ) enables folks to extend this pen in some pretty unbelievable ways. Check out this case study on how the pen was used at the recent G8 summit to enable non-technies to do some pretty amazing collaboration.

Creating a plug-in using the io2 SDK is a little complex if you were to do it from scratch. However, when you install the SDK in adds a new "Logitech io2 Plug-in" project when you use File > New Project from within Visual Studio. It also includes default plug-in templates in both C# and VB. I started with the default C# plug-in. You just derive your plug-in from Logitech.Plugins.AbstractPlugin.

Visual C#


using System;
using System.Diagnostics;
using Microsoft.Win32;
using System.IO;
using Logitech.PlugIns;
using Logitech.Pen.Ink.Sdk;

namespace Hanselman.BlogJetPlugIn
{
public class PlugIn : AbstractPlugIn
{
public PlugIn(IPlatform platform) : base(platform){}

public override void Init(){base.Init();}

public override void Dispose(){}

public override void SelectionChanged()
{
base.SelectionChanged ();
}

public override object Run(IAction action,
ISelection selection, object[] parameters)
{
//My plugin will go here!
}
}
}

My vision is that I'll write up a blog post using the digital pen and paper, dock the pen, then from the Logitech organizer software select a menu my plug-in will add like "BlogJet this page..." and the digital ink would be transfered to BlogJet and then to my blog running DasBlog. Seems complex, but the flow is very simple. Write paper, dock, click, blogged. 

BlogJet

BlogJet is a small and elegant offline blogging tool. I say offline because BlogJet is a smart client that you install and run on your system, offline if you like. You can post when you're back online. I like BlogJet because is includes spell checking, image resizing and, more importantly, it supports posting to dozens of blogging engines. I use DasBlog for my blogging engine, and since DasBlog supports the standard MetaWeblog API for posting, I can use BlogJet to post to my blog without using a browser. You don't need to worry about the details of MetaWeblog or Blogger or the other blogging APIs; it's all handled for you. BlogJet also supports uploading images, which isn't supported directly by MetaWeblog, by uploading them in parallel via FTP. All in all, it fit my needs perfectly.

BlogJet supports two ways of automating posting. You can use their -blogthis command line switch and include the contents you want posted in the clipboard, or you can write your content out to a temp directory as an HTML file and call BlogJet with that file as a parameter. It will automatically convert file:/// references to images into http:/// blog-relative references. This will make integration with the pen easy, as the Pen SDK supports getting bitmaps of the digital ink.

As an aside, I took the BlogJet "little red man" icon and overlaid a Logitech io2 Pen and used this as my Toolbar icon to expose my functionality within the Logitech Organizer.

Click here for larger image

(Click image to zoom)

The Code

Everything happens in the Run method. The action is passed in as an IAction that would allow me to do different things based on context if I cared. ISelection holds just that, the selected documents. I need to pass the selected items into a helper method that will write out a temporary HTML document and separate images for each page. I needed to get the installed location of the BlogJet software from the registry (I found this by poking around.) Then I start a new process passing in BlogJet.exe's location surrounded by quotes, as well as the full path to the temporary HTML file that contains <img> tags pointing to each of the pages.

Visual C#


using System;
using System.Diagnostics;
using Microsoft.Win32;
using System.IO;
using Logitech.PlugIns;
using Logitech.Pen.Ink.Sdk;

namespace Hanselman.BlogJetPlugIn
public override object Run(IAction action,
ISelection selection, object[] parameters)
{
try
{
WebPageMaker webPageMaker = new WebPageMaker(Platform);
string htmlFileUrl = webPageMaker.Make(selection.SelectedItems);

RegistryKey key = Registry.CurrentUser.OpenSubKey(
@"Software\DiFolders Software\BlogJet");
string BlogJetPath = key.GetValue("InstDir") as string;
BlogJetPath = "\"" + Path.Combine(BlogJetPath,"BlogJet.exe") + "\"";

ProcessStartInfo startInfo = new ProcessStartInfo(BlogJetPath);
startInfo.Arguments = "\"" + htmlFileUrl + "\"";
Platform.LogMessage(false,startInfo.FileName);

startInfo.UseShellExecute = true;
Process.Start(startInfo);
}
catch(PlugInTemplateException pe)
{
Platform.LogMessage(true, pe.Message);
}
catch(Exception e)
{
Platform.LogMessage(true, e.Message);
}

return null;
}

Here's a bit of a simplification of what is done in WebPageMaker. You can take a look at the source for more details.

Visual C#

StreamWriter writer = File.CreateText(htmlFilePath);
writer.WriteLine("<p>");
foreach(ISelectedItem selectedItem in selectedItems)
{
IDocument document = (IDocument)selectedItem.Object;
if(!document.IncludesStrokes) DocumentSerializer.Load(document);
for (int pageIndex = 0; pageIndex < document.Pages.Count; pageIndex++)
{
string imagePath = Path.GetFileNameWithoutExtension(
document.Name) + pageIndex.ToString("000") + ".jpg";
Regex reg = new Regex("[^a-zA-Z0-9. ]");
pageFilePath = Path.Combine(Path.GetTempPath(), reg.Replace(
Path.GetFileName(pageFilePath),String.Empty));
Bitmap bitmapImage = ImageGeneratorFactory.Create(
document.Pages[pageIndex]).GetBitmap();
bitmapImage.Save(pageFilePath, ImageFormat.Jpeg);
writer.WriteLine(string.Format(@"<img src=""{0}"">", imagePath));
}
}
writer.WriteLine("</p>");
writer.Close();


This little chunk of code creates a text file using a StreamWriter and spins through the selected items. Then it spins through each page within the document and generates an image in a temporary file that is a picture of the digital ink.

There is a little hack in there as BlogJet has some trouble with Unicode characters within a filename. They seem to get double UrlEncoded, so I just strip out everything that's not A to Z, a number or a period.

"Plugging in" multiple places

Logitech was serious when they called this a Plug-in Toolkit. A finished plug-in doesn't show up in just one place—it's plugged into the complete io2 pen experience. I personally didn't expect this level of integration. I figured I'd get a right-click menu, or a toolbar button. Once my action was defined in the Run method within my code, I had to create a Plugin.xml file that defined all the places I wanted my new action to be available. For example, when you right-click on a .pen file within your My IO Documents folder, there's an "IO Actions" menu. I'd like to be in there.

Click here for larger image

(Click image to zoom)

Instead of messing around with Explorer and the complexities of shell integration, the SDK lets me add a menu item by adding these lines to my Plugin.xml file.


<Extension Point="Menus" ApplicationId="Logitech.Pen.ShellExtension">
<ObjectContribution
ObjectClass="Logitech.Pen.Ink.Sdk.IDocument">
<Action Id="Hanselman.BlogJetPlugIn.Menus6.Send"
DisabledLabel = "%BlogJetPlugInDisabledLabel"
Label="%BlogJetPlugInLabel"
Description="%BlogJetPlugInDescription"
Path = "Menus/ContextMenu/BlogJetPlugIn"
Index = "7"/>
</ObjectContribution>
</Extension>

There's also a Plugin.resx that keeps all my localized text. That's what the strings that start with % refer to. The Pen SDK will automatically pull text out of the .resx.

Since your plug-in assembly will run in-process in not only Explorer but also the Logitech Organizer software, debugging could be a little tricky. Logitech makes this much easier by including a "Plug-ins Test Platform" that will host your plug-in, provide toolbars, menus and even includes sample pages to test with.

ioTags

The latest version of the io2 Software added a new feature called IOTags. Basically, while you're writing some text, you add a circle with a letter inside, and then draw a vertical line to encompass the significant text. I figured that could be useful to me as well, so I added a few more lines to my Plugin.xml file that would automatically blog text marked with the "B" IOTag.

 
<Extension Point="Automation">
<ObjectContribution
ObjectClass="Logitech.Pen.Ink.Sdk.IDocument">
<Action
Id = "Hanselman.BlogJetPlugIn.Automation.Send"
Description = "%BlogJetPlugInAutomationDescription">
<Data>
<IoTags FieldSeparator=";">
<IoTag Tag="B">
<Field Id="Subject" Type="Text" />
</IoTag>
</IoTags>
</Data>
</Action>
</ObjectContribution>
</Extension>

 
Again, I was able to do this without checking my code at all. Certainly if I wanted to recognize this new action and do something different I could, but in this instance I wanted to make it as convenient as possible for me to blog with this tool. Otherwise I wouldn't be as likely to blog!

At this point I can blog using the pen by:

  • Right-clicking a file in Explorer
  • Using a menu or toolbar button within the Logitech Pen Organizer
  • Using the "B" IOTag

The IOTag is nice because it implies immediate action. The blog post occurs immediately after docking the pen.

Targeting .NET 1.1 with Visual Studio 2005

I got deep into this project before I started hosting my plug-in within Logitech's framework. I had been happily working in Visual Studio 2005 and the .NET Framework 2.0. I hadn't used any 2.0 libraries in this simple project, but I was using all the new shiny features of the new Visual Studio IDE. But, tragedy struck when I realized that the current (as of this writing) Logitech io2 SDK isn't compatible with .NET 2.0. Would I have to switch back to Visual Studio 2003? Such a thing was unthinkable!

Click here for larger image

(Click image to zoom)

MSBUILD to the rescue! Visual Studio 2005 uses a powerful and extensible build mechanism to handle compiles called MSBUILD. MSBUILD uses a default XML configuration file called a "targets" file. The system is so extensible that I could use a custom .target file to target the .NET 1.1 compiler with the 2005 IDE. This means my development environment had all the new bells and whistles of Visual Studio 2005 while maintaining compatibility with this .NET 1.1 version of the Logitech SDK. See http://www.hanselman.com/blog/BuildingNET11ProjectsUsingVisualStudio2005.aspx for more details on this custom target file from Gustavo Guerra.

Note   While MSBUILD is extensible for a reason, my way is not a currently (as of this writing) supported way of doing things. That means, if it doesn't work for you, you don't get to complain! The good news is that Microsoft officially announced on November 9th, 2005 that they would be creating the MSBuild Everett Environment (MSBEE). I will update my sample to use the official technique as soon as it is available. I'm very excited about this because it makes the whole Visual Studio 2005 story that much more compelling.

The result of all this can be seen on my blog at http://www.hanselman.com/blog/BloggingDirectlyFromALogitechIO2Pen.aspx

Conclusion

There's things that could be extended, added, and improved on with this project. Here are some ideas to get you started:

  • Use Logitech's OCR software to recognize the digital ink and post text instead!
  • Make a blog-engine specific plug-in rather than using BlogJet. Post to MSN Spaces or Blogger directly.
  • Post digital ink to Flickr or SmugMug.

Have fun and have no fear when faced with the words: Some Assembly Required!

Follow the Discussion

  • SarasMaxSarasMax

    I didn't understand what is this topic about? i reached this page from google in searching "C# code for digital pen". I want ro write a code in c# which doctors can write eye information like "+0.75+1.00*180" with digital pen on picture control and can save, erase and print it, but before that, program should recognize the text and store it as string in sql database. Can you help me?

  • sandip.punekarsandip.​punekar

    it work on lcd display,how it work,where i can purchase this product.

  • CammeCamme

    I was just looking for something like this and it sounds great. Already have the pen, but the functionality avaliable isnt enough.

    My only problem now is that the SDK has been removed (or just moved) from the logitech site and i cant find it anywhere.

    Do you still got it or do you know where I can find it?

    Cheers

  • Clint RutkasClint I'm a "developer"

    @SaraX you can use the built in tablet support in the operating system to do this.  If you want your application to have Ink support, there is an Ink object in .Net too

  • SaraXSaraX

    I need to use the pen to write in a text box forexample,can i use this codes?

  • My Little BlogMy Little Blog

    great idea..thanks for sharing it.

Remove this comment

Remove this thread

close

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.