This page drives you through available possibilities to import content into iink SDK or to export it for external usage.
You can import data into content blocks. For example, the following code will import the “Hello iink SDK” text string into a “Text” part:
editor.import(mimeType: IINKMimeType.text, data: "Hello iink SDK", selection: editor.rootBlock)
In this case, you could have omitted to specify the block. As the part only hosts a single root block, iink SDK can figure by itself where to import the content:
editor.import(mimeType: IINKMimeType.text, data: "Hello iink SDK", selection: nil)
For parts that can host multiple blocks, such as “Text Document” parts, you need to explicitly specify the target block.
If it does not exist yet, you can call addBlock(at:type:)
and directly pass the data to import.
The list of supported mime types for a given block can be obtained by calling supportedImportMimeTypes(forSelection:)
on the editor. For instance:
let supportedImportMimeTypes = editor.supportedImportMimeTypes(forSelection: editor.rootBlock)
When it comes to textual data, JIIX import is currently limited to text words or characters candidate changes. More import capabilities will be provided later on.
To change the text candidates within a given Text, Raw Content or Diagram block:
label
of the target word
(or character
) with another word (or character) from the candidates
list.When importing JIIX into “Diagram” and “Raw Content” parts, the performed action depends on the configured properties diagram.import.jiix.action
and raw-content.import.jiix.action
. So you should tune them according to your need:
When the property is set to update
, iink changes the text candidates as described above. This is the default action for “Diagram” parts.
When the property is set to add
or replace
, iink imports the ink data: strokes, glyphs and primitives. Note that this does not reinject recognition results and iink triggers a new recognition.
The remainder of this paragraph applies to add
and replace
actions.
The difference between both actions, is that in the replace
case, iink performs a clear, this removing all content from the part, before importing the ink data. The default action for “Raw Content” parts is add
.
In order to ease the import of the ink data at a given position, you can add a “transform” key into your jiix to apply this transform on the jiix data. The json syntax is “transform”: [xx, yx, tx, xy, yy, ty]. You can see the Transform API for details on the transform components.
Let’s take as an example the following use case. Imagine you want to double the size of one text node into a “Diagram” part. Here is how to proceed:
...
{
"type": "Text",
"parent": 183,
"id": 190,
"bounding-box": {
"x": 58.4949799,
"y": 31.677475,
"width": 10.9569321,
"height": 5.24174881
}, ...
...
{
"type": "Text",
"parent": 183,
"id": 190,
"transform": [ 2, 0, -63.973446 , 0, 2, -34.298349],
"bounding-box": {
"x": 58.4949799,
"y": 31.677475,
"width": 10.9569321,
"height": 5.24174881
},...
You can temporarily “override” the current editor configuration for the need of a specific import. For instance, in the case of “Diagram” and “Raw Content” parts, it might be convenient to momentarily modify the current editor configuration for the need of changing the text candidates, without impacting your global or your editor configurations. You can perform such a specific import using the method illustrated by the following example:
// Create an empty parameter set
let importParams:IINKParameterSet = engine.createParameterSet()
// Set the appropriate configuration to set import action for candidate update
importParams.set(string: "update", forKey: "raw-content.import.jiix.action")
// Import into your block the jiixString corresponding to your updated candidate
editor.import(mimeType: IINKMimeType.JIIX, data:jiixString, selection:currentBlock, overrideConfiguration: importParams)
To import raw ink content, instantiate an editor and pass it an array of pointer events. Note that in this scenario, except if you are working on a “Drawing” part, the recognition engine will automatically process the new strokes. This approach is documented in the Editing part of this guide.
Recognition can sometimes take a certain time to complete, especially if you send many strokes to the editor at once.
If you want to make sure that you export the final recognition results, you have to call waitForIdle
before export()
.
Export operations are made on content blocks or selections. For instance, this allows you to export a specific diagram from a Text Document part).
You can retrieve the list of supported export mime types for a given block or selection by calling supportedExportMimeTypes(forSelection:)
on the editor:
let supportedExportMimeTypes = editor.supportedExportMimeTypes(forSelection: editor.rootBlock)
To export content, call the export()
method of the editor object, passing it the block or selection to export and the desired mime type:
// Export a math block to MathML
let result = editor.export(selection: mathBlock, mimeType: IINKMimeType.mathML)
// Export a text document to docx
let fullPath:String = FileManager.default.pathForFileInDocumentDirectory(fileName: "document.docx")
editor.export(block: textDocBlock, toFile: fullPath , mimeType: IINKMimeType.DOCX ,imagePainter: imagePainter)
The API provides a convenience method that lets you omit the mime type if iink SDK is able to guess it unambiguously from the file extension:
// Export a text document to docx
let fullPath:String = FileManager.default.pathForFileInDocumentDirectory(fileName: "document.docx")
editor.export(block: editor.rootBlock, toFile: fullPath, mimeType: IINKMimeType.DOCX, imagePainter: imagePainter)
IINKMimeTypeGetFileExtensions:
method defined in the IINKMimeTypeValue
class from the IINKMimeType.h
header file to get
the extensions supported for a given mime type.
Certain formats require you to provide an object conforming to the IINKImagePainter
protocol to let iink SDK generate images from the content. This is
expectedly the case for png
and jpeg
exports, but also for formats such as docx
.
A default, ready-to-use, image painter implementation is provided by MyScript as part of the UI Reference Implementation.
If the format does not require an image painter, you can provide the export method with a null pointer instead.
Textual format exports are returned as a string that can then be programmatically manipulated. Binary formats, on the other hand, are saved as files on the disk at a location you can specify.
let imageLoader:ImageLoader = ImageLoader()
imageLoader.editor = editor
let imagePainter:ImagePainter = ImagePainter.init(imageLoader: imageLoader)
let exportFullPath:String = FileManager.default.pathForFileInDocumentDirectory(fileName: "export.docx")
editor.export(selection: editor.rootBlock, toFile: exportFullPath , imagePainter: imagePainter)
You can call the IINKMimeTypeIsTextual:
method defined in the IINKMimeTypeValue
class of the IINKMimeType.h
header file to know whether a format is
textual or binary.
Some export functions let you temporarily “override” the current editor configuration for the need of a specific export. This is useful if you want to tune the export parameters (like the type of information to export to JIIX) without impacting your global or your editor configurations.
The following example shows how you can export a block recognition result as JIIX without including original ink information:
// Create an empty parameter set
let params:IINKParameterSet = engine.createParameterSet()
// Set the appropriate configuration to exclude strokes from the export
params.set(boolean: false, forKey: "export.jiix.strokes")
// Export a block with the new configuration
let jiix = editor.export(block: editor.rootBlock, mimeType: IINKMimeType.JIIX, overrideConfiguration: params)
Image export can apply to a part only of the page or more than the chosen block extent. You can also choose whether guides appear or not in the image. For details about the image export properties, refer to the configuration page
In order to export image, an image painter object is necessary as described in this section
The following example illustrates the export as a PNG image of a viewport. The guides are visible:
// Create an empty parameter set
let imageParams:IINKParameterSet = engine.createParameterSet()
// Set the appropriate configuration to tune the viewport to export
let originPx = Double(100)
let widthPx = Double(100)
let heightPx = Double(200)
imageParams.set(number: originPx, forKey:"export.image.viewport.x")
imageParams.set(number: originPx, forKey:"export.image.viewport.y")
imageParams.set(number: widthPx, forKey:"export.image.viewport.width")
imageParams.set(number: heightPx, forKey:"export.image.viewport.height")
// Set the appropriate configuration to enable the guides into the exported image
imageParams.set(boolean: true,forKey: "export.image.guides")
// Create the image painter
let imageLoader:ImageLoader = ImageLoader()
imageLoader.editor = editor
let imagePainter:ImagePainter = ImagePainter.init(imageLoader: imageLoader)
let fullPath:String = FileManager.default.pathForFileInDocumentDirectory(fileName: "ImageFileName.png")
// Export the image with the customised parameters
editor.export(block: editor.rootBlock,toFile: fullPath, mimeType: IINKMimeType.PNG,imagePainter: imagePainter, overrideConfiguration: imageParams)
MyScript iink SDK defines its own format, called JIIX (short for JSON Interactive Ink eXchange format).
This format provides a consistent representation of the different types of content that are supported, covering semantics, positions, styling and ink-related aspects.
Thanks to its JSON syntax, it stays readable and can be easily parsed, making it appropriate to exchange information with the host application or as a transitory representation to support custom export formats.
MyScript iink SDK allows you to import and export some commonly used formats, such as LaTeX for math content or Docx in the case of Text Document blocks. The full list can be found here.
The next part of the guide will talk about zooming and scrolling.