This page explains how you can use Interactive Ink SDK without a graphical interface.
Interactive Ink SDK was primarily designed as a graphical-oriented, interactive solution that lets end users easily input and edit their handwriting.
Sometimes, however, it makes sense to integrate iink SDK off-screen, without any user interface. It may be required to add handwriting recognition capabilities to an existing non-interactive application or to process input “in the background”, for instance to implement an ink search indexing service.
Common off-screen use cases often consist in batch processing content, i.e. processing a series of pointer events and exporting a result.
Off-screen setup is very similar to the graphical use case:
- Create and configure an engine.
- Create a renderer from the engine and pass it a null render target.
- Create a package and a content part of the appropriate type to work on.
- Create an editor, set its view size and attach a font metrics provider (for most platforms, you can reuse the one coming with the UI Reference Implementation).
- Attach the part to the editor.
- dpi values - Although you do not display the strokes, you need to provide proper dpi values to the renderer. These correspond to the “resolution” of your input surface, be it a digital screen or a sheet of paper. They will provide the recognizer with a sense of “writing scale” and help it favor the right hypotheses.
- Text guides - As explained in the editing part, text guides improve the recognition accuracy, provided that handwriting uses them as baselines. If handwriting does not match the guides, however, the quality of the recognition can be negatively impacted. In most off-screen scenarios, it is thus recommended to turn them off.
- Editor view size - The editor requires you to provide a size before setting the part. This size shall be consistent with your writing surface and the dpi values you provided to the renderer. It will be used by some export options.
- Font metrics provider - Although you may not want to explicitly convert, you need to attach a font metrics provider to the editor before setting the part. This is because font metrics are useful beyond mere display, like for content layout management or some export options.
Clear the editor between sessions - A common mistake in batch mode is to forget cleaning the part between imports, which causes new ink to be stacked on top of the one from the previous session. In most cases, you thus have to clear the part before processing new input. Creating a new part for each new session and removing the previous one will free the memory from a potentially unwanted undo/redo history.
Gesture processing - When calling
pointerEvents:count:doProcessGestures:error:on the editor, make sure to set the
NO/falseto avoid side-effects and lengthy recognition time.
Export after recognition is complete - Make sure to call
waitForIdleon the editor to wait for the recognition to complete before exporting.
// Configure the engine to disable guides (recommended) [engine.configuration setBoolean:NO forKey@"text.guides.enable" error:nil]; // Create a renderer with a nil render target float dpiX = ...; float dpiY = ...; IINKRenderer *renderer = [engine createRendererWithDpiX:dpiX dpiY:dpiY target:nil]; // Create the editor IINKEditor *editor = [engine createEditor:renderer]; // The editor requires a font metrics provider and a view size *before* calling setPart: FontMetricsProvider *fontMetricsProvider = [[FontMetricsProvider alloc] init]; [editor setFontMetricsProvider:fontMetricsProvider]; [editor setViewSize:CGSizeMake(640, 480)]; // Create a temporary package and part for the editor to work with IINKContentPackage *package = [engine createPackage:@"text.iink" error:nil]; IINKContentPart *part = [package createPart:@"Text" error:nil]; [editor setPart:part];