Tablet PC: Performing handwriting recognition with an arbitrary recognizer using RecognizerContext
By default, when you instantiate a RecognizerContext object you get either a recognizer that supports the current input locale for the OS, or if no recognizer matches the input locale, the English recognizer. That works for most situations, but what if you want to use another recognizer that is installed on your system? The answer is to created a Recognizers collection. This will allow you to iterate over the collection of recognizers, and to select the appropriate recognizer based on its name, supported languages, etc.
Example of finding a recognizer that supports a particular language:
// Language ID for Japanese short targetLanguage = 1041; Recognizers theRecognizers = new Recognizers(); Recognizer recoSupportsJapanese = null; foreach (Recognizer reco in recognizers) { foreach (short LCID in reco.Languages) { if (LCID == targetLanguage) { recoSupportsJapanese = reco; break; // Exit the inner foreach } } if (recoSupportsJapanese != null) { break; // Exit the outer foreach } } |
Following the execution of the code above, you would check recoSupportsJapanese against null to determine whether a recognizer supporting Japanese was found. If it was not found, you would prompt the user, disable the input control, or perhaps use another recognizer.
In the following example, I’ve taken our basic Ink application, and dropped on a combo box that gets populated with the names of the recognizers installed on the system. When perform recognition, the corresponding recognizer is used. This simple example shows how to use an arbitrary recognizer, and can also be used to determine what recognizers are installed on the system.
Tech Note: You can see which recognizers are installed on your system by examining the following key in the registry:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\TPG\System Recognizers
Under that key, there are separate keys (corresponding to the GUID for the recognizer) for each recognizer that is installed.
Example Code:
// // Basic Ink enabled Windows Forms application with // handwriting recognition using RecognizerContext // Gavin Gear - https://blogs.msdn.com/gavingear // 08/2006 // using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using Microsoft.Ink; // The managed Tablet PC API namespace BasicInkApplication { public partial class BasicInkApplication : Form { // The InkOverlay that we'll attach to our Form private InkOverlay inkOverlay; private Recognizers recognizers; public BasicInkApplication() { InitializeComponent(); // Create an InkOverlay object that's attached to the Form this.inkOverlay = new InkOverlay(this); // Enable the InkOverlay (default is Enabled == false) this.inkOverlay.Enabled = true; // The InkOverlay needs to be disposed due to unmanaged resources // used by the InkOverlay this.FormClosing += new FormClosingEventHandler(BasicInkApplication_FormClosing); // Populate the recognizers dropdown with the recognizers // that are installed on the system recognizers = new Recognizers(); foreach (Recognizer reco in recognizers) { int index = this.comboBoxRecognizers.Items.Add(reco.Name); } this.comboBoxRecognizers.SelectedIndex = 0; } void BasicInkApplication_FormClosing(object sender, FormClosingEventArgs e) { this.inkOverlay.Dispose(); } private void buttonRecognize_Click(object sender, EventArgs e) { // Instantiate a RecognizerContext object using the // Recognizer.CreateRecognizerContext() method where // we are using the selected index of the ComboBox // to get the corresponding recognizer from the Recognizers // collection RecognizerContext context = this.recognizers[this.comboBoxRecognizers.SelectedIndex].CreateRecognizerContext();
// Add the strokes collected by our InkOverlay context.Strokes = this.inkOverlay.Ink.Strokes; // Perform recognition, pass a RecognitionStatus object // that will give the status of the recognition RecognitionStatus status; RecognitionResult result = context.Recognize(out status); MessageBox.Show(result.TopString); context.Dispose(); // Free the unmanaged resources } } } |
**Note that on non-Tablet PC OS platforms, you'll need to install the recognizer pack, otherwise the RecognizerContext object will throw an exception when it is instantiated. You can download the recognizer pack from the following location:
Check out the screenshot attachments demonstrating different recognition results for different languages. That covers the basics of using an arbitrary recognizer… It’s really not that difficult.
See Ya-
Gavin