编码
Universal Ink Model被序列化为Protocol Buffers v3 message,包含在RIFF container.中 下面的章节描述了容器和protobuf序列化方案。
RIFF Container
Universal Ink Model (UIM)被序列化为RIFF container,包含在@@@中RIFF chunk UIM3. 该数据块包含两个子数据块,分别是HEAD和DATA。 HEAD数据块包含最新版的规范。 该版本使用3字节编码,定义如下:[major-version]-[minor-version]-[patch-version]。
如第8.2节“Protocol Buffers序列化方案”中所述,墨水模型被序列化为Protocol Buffers消息,保存在DATA数据块中。

图1:RIFF 图
Ink Tree
墨水树以一般节点结构构建。
构建树时,depth属性反映树的深度。
对于树结构的序列化,采用深度优先预排序树序列化,如图3所示。
每个节点都有一个唯一 标识符id,它与语义语句有关,作为主语的标识符。
index属性关联着路径或传感器数据索引。
groupBoundingBox是可选项,提供视觉辅助,以方便调试,或高亮显示包含可单击选项的相关区域。
仅当节点的type为CHUNK时,属性chunkFromIndex和chunkToIndex才会与子索引有关。

图2:深度优先树顺序(红色):F、B、A、D、C、E、G、I、H。
数据压缩
编码
编码过程如下:
**第1步:(可选)**使用外部指定的小数精度将浮点值转换为整数值:
integerValue = floatValue * (10 ^ decimalPrecision);
Note: 第1步仅适用于不是整数的数据类型(例如,@@@UINT32, UINT64, INT32, or INT64).
**第2步:**对转换值执行增量(Delta)编码:
encodedValues[0] = integerValues[0];
for(i = 1; i < n; i++)
{
encodedValues[i] = integerValues[i] - integerValues[i - 1];
}
**注意:在浮点值和定点(整数)值之间转换时,可能会有精度损失。
如果精度对应用功能极为关键,必须予以考虑。
一个可行的解决方案是通过IEEE 754:执行转换,这种情况下,对于每个被转换的值,都应使用合适的decimalPrecision以及一个在转换过程中保持不变的近似值。
Decoding
要恢复原始值,可按照下面的方法逆转编码过程:
**第1步:**执行增量(Delta)编码,恢复整数值:
integerValues[0] = encodedValues[0];
for(i = 1; i < n; i++)
{
integerValues[i] = integerValues[i - 1] + encodedValues[i];
}
第2步:(可选) Convert integer values to floating-point values using externally-specified decimal precision:
floatValue = integerValue / (10 ^ decimalPrecision)
***注意:***第2步仅适用于不是整数的数据类型。
Protobuf序列化方案
BrushPrototype
刷子的多边形原型定义。
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| coordX | float | 重复 | 刷子原型的x坐标列表 。 |
| coordY | float | 重复 | 刷子原型的y坐标列表。 |
| coordZ | float | 重复 | 刷子原型的z坐标列表[用于3D渲染]。 |
| indices | uint32 | 重复 | 刷子原型的索引列表[用于3D渲染]。 |
| shapeURI | string | 可选 | 唯一标识形状多边形的URI。 |
| size | float | 可选 | 定义路径点的原型大小。 |
Brushes
用于墨水光栅化所需的刷子描述。
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| vectorBrushes | VectorBrush | 重复 | 已定义的矢量刷子列表。 |
| rasterBrushes | RasterBrush | 重复 | 已定义的光栅刷子列表。 |
ChannelData
数据项列表。
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| sensorChannelID | string | 可选 | 通过ID引用墨水 传感器通道。 |
| values | sint32 | 重复 | 使用提供的精度增量编码的样本值。 |
Environment
环境 定义了关于输入环境的所有细节:
- 操作系统:名称、版本等。
- 应用程序:名称、版本等。
- 地理信息:GPS坐标。
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| id | string | 可选 | 根据MD5哈希生成的MD5哈希值,符合MD5哈希值唯一标识符生成方案。 |
| properties | Property | 重复 | 环境属性,例如操作系统名称、操作系统版本等。 |
Float32
浮点值的包装器,用于避免跨平台零值问题。
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| value | float | 可选 | 消息内部包装的浮点值。 |
InkData
包含所有墨水数据。
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| strokes | Stroke | 重复 | 用于存储笔画的数据容器。 |
InkInputProvider
输入提供程序类型的定义。
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| id | string | 可选 | 根据MD5哈希值生成,符合MD5哈希值唯一标识符生成方案。 |
| 类型 | InkInputProviderType | 可选 | 使用的硬件类型 - PEN、TOUCH、MOUSE、或控制器。 |
| properties | Property | 重复 | InkInputProvider 属性,如 PenID。 |
InkObject
墨水对象作为捕获所有相关数据的基本结构。
- 从输入传感器记录的传感器数据
- 定义所使用的不同刷子类型的刷子配置
- 具有墨水笔画视觉几何的墨水数据
- 用于结构化墨水数据的墨水树
- 描述作者、文档等的元数据
- 具有语义的知识图
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| inputData | InputData | 可选 | 与墨水输入相关数据的数据容器。 |
| inkData | InkData | 可选 | 与墨水相关的墨水数据的数据容器。 |
| 刷子 | Brushes | 可选 | 光栅化工具。 |
| inkTree | Node | 重复 | 墨水树:这是以墨水为中心的数据模型。 |
| 视图 | View | 重复 | 基于知识图的墨水树的视图列表。 |
| knowledgeGraph | TripleStore | 可选 | 知识图。 |
| 变换 | Matrix4 | 可选 | 变换是应用于所有路径的仿射变换矩阵。 |
| properties | Property | 重复 | 文档相关的属性,如 DOCUMENT、AUTHOR、LAST_MODIFIED等。 |
InputContext
捕获墨水设备的上下文,参考环境和 SensorContext。
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| id | string | 可选 | 根据MD5哈希值生成,符合MD5哈希值唯一标识符生成方案。 |
| environmentID | string | 可选 | 参考环境。 |
| sensorContextID | string | 可选 | 参考 SensorContext。 |
InputContextData
上下文和输入定义的容器结构。
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| inputContexts | InputContext | 重复 | 输入上下文的列表。 |
| inkInputProviders | InkInputProvider | 重复 | 输入提供程序的列表。 |
| inputDevices | InputDevice | 重复 | 输入设备的列表。 |
| environments | Environment | 重复 | 环境设置的列表。 |
| sensorContexts | SensorContext | 重复 | 传感器上下文的列表。 |
InputData
InputData捆绑输入。
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| inputContextData | InputContextData | 可选 | 输入上下文数据。 |
| sensorData | SensorData | 重复 | 传感器数据的数据容器。 |
InputDevice
InputDevice 与其属性。
属性可以包括:
- 通信协议: USB、BTC、BLE、SPP、WIFI
- 通信ID:VID、PID;MAC;UID;COM_PORT
- 设备名称: Wacom Intuos Pro M、Apple iPad 8、Samsung GalaxyTab 10
- 序列号
- 固件版本(MCU)
- 次要固件版本 (BT、WIFI)-不同模块提供其自身的版本
- 方向: PORTRAIT、LANDSCAPE、PORTRAIT_REVERSE、LANDSCAPE_REVERSE 或 0、90、180、270
- 传感器尺寸
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| id | string | 可选 | 根据MD5哈希值生成,符合MD5哈希值唯一标识符生成方案。 |
| properties | Property | 重复 | InputDevice 属性。 |
Matrix4
4x4仿射矩阵的表示
| m00 m01 m02 m03 | | m10 m11 m12 m13 | | m20 m21 m22 m23 | | m30 m31 m32 m33 |
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| m00 | float | 可选 | |
| m01 | float | 可选 | |
| m02 | float | 可选 | |
| m03 | float | 可选 | |
| m10 | float | 可选 | |
| m11 | float | 可选 | |
| m12 | float | 可选 | |
| m13 | float | 可选 | |
| m20 | float | 可选 | |
| m21 | float | 可选 | |
| m22 | float | 可选 | |
| m23 | float | 可选 | |
| m30 | float | 可选 | |
| m31 | float | 可选 | |
| m32 | float | 可选 | |
| m33 | float | 可选 |
Node
用于定义树结构的节点消息。
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| id | string | 可选 | 节点唯一标识符 |
| depth | uint32 | 可选 | 在层次结构中的深度 |
| index | uint32 | 可选 | 在InkData.paths 或 InkData.sensorData 数据持有者中的索引 |
| Type | NodeType | 可选 | (路径和传感器数据节点仅限)节点类型 |
| groupBoundingBox | Rectangle | 可选 | 边界框(仅适用于组节点) |
| chunkFromIndex | uint32 | 可选 | 块的开始位置(仅限CHUNK节点) |
| chunkToIndex | uint32 | 可选 | 块的结束位置(仅限CHUNK节点) |
PathPointProperties
不变的管道属性。变量属性通过Stroke消息进行序列化。
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| size | Float32 | 可选 | 笔刷大小 |
| red | Float32 | 可选 | 红色通道的颜色值[0, 1] |
| green | Float32 | 可选 | 绿色通道的颜色值[0, 1] |
| blue | Float32 | 可选 | 蓝色通道的颜色值[0, 1] |
| alpha | Float32 | 可选 | alpha通道的颜色值[0, 1] |
| rotation | Float32 | 可选 | 笔刷的z轴旋转 |
| scaleX | Float32 | 可选 | 笔刷的x轴缩放 |
| scaleY | Float32 | 可选 | 笔刷的y轴缩放 |
| scaleZ | Float32 | 可选 | 笔刷的z轴缩放[用于3D渲染] |
| offsetX | Float32 | 可选 | 笔刷的x轴偏移 |
| offsetY | Float32 | 可选 | 笔刷的y轴偏移 |
| offsetZ | Float32 | 可选 | 笔刷的z轴偏移[用于3D渲染] |
Property
编码单个属性
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| name | string | 可选 | 属性的名称 |
| value | string | 可选 | 属性的值 |
RasterBrush
使用光栅图像定义的笔刷
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| name | string | 可选 | 笔刷描述符。 |
| spacing | float | 可选 | 相邻粒子之间的距离。 |
| scattering | float | 可选 | 沿曲线法线的散射。 |
| rotationMode | RotationMode | 可选 | 笔刷的粒子旋转模式。 |
| shapeTexture | bytes | 重复 | 包含形状纹理的PNG图像列表。 |
| shapeTextureURI | string | 重复 | 与形状纹理关联的URI列表。 |
| fillTexture | bytes | 可选 | 包含填充纹理的PNG图像列表。 |
| fillTextureURI | string | 可选 | 标识填充纹理的URI。 |
| fillWidth | float | 可选 | 填充瓦片的宽度。 |
| fillHeight | float | 可选 | 填充瓦片的高度。 |
| randomizeFill | bool | 可选 | 指定填充纹理是否随机位移。 |
| blendMode | BlendMode | 可选 | 应用的混合模式。 |
Rectangle
矩形的表示形式
| 字段 | 标签 | 描述 |
|---|---|---|
| x | float | 可选 |
| y | float | 可选 |
| width | float | 可选 |
| height | float | 可选 |
SemanticTriple
语义三元组,或简称三元组,是原子数据实体数据模型。顾名思义,三元组是一组三个实体,以主谓宾表达式的形式编码了关于语义数据的陈述。
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| subject | string | 可选 | |
| predicate | string | 可选 | |
| object | string | 可选 |
SensorChannel
关于传感器通道的信息。
支持的通道类型:
- will:///input/3.0/channel/X
- will:///input/3.0/channel/Y
- will:///input/3.0/channel/Z
- will:///input/3.0/channel/Timestamp
- will:///input/3.0/channel/Pressure
- will:///input/3.0/channel/RadiusX
- will:///input/3.0/channel/RadiusY
- will:///input/3.0/channel/Altitude
- will:///input/3.0/channel/Azimuth
- will:///input/3.0/channel/Rotation
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| id | string | 可选 | 根据MD5哈希基于MD5哈希的唯一标识符生成方案。 |
| Type | string | 可选 | 描述此通道的唯一URI。支持的类型有: |
| metric | InkSensorMetricType | 可选 | 用户定义的通道应该从用户方提供自定义含义。指示用于计算数据项分辨率的度量。 |
| resolution | double | 可选 | 是一个十进制数,给出数据项增量的数量。 |
| min | float | 可选 | 每个物理单位。例如,如果物理单位是米和设备单位。/ 分辨率为100000,那么值150将为0.0015米。通道的最小值。 |
| max | float | 可选 | 通道的最大值。 |
| precision | uint32 | 可选 | 整数编码的精度,用于编码的浮点值。 |
SensorChannelsContext
传感器通道上下文 SensorChannelsContext 将产生相同采样率的数据的传感器通道分组。
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| id | string | 可选 | 根据MD5哈希基于MD5哈希的唯一标识符生成方案。 |
| channels | SensorChannel | 重复 | 此组中的通道提供相同时间的对齐值。 |
| samplingRateHint | Uint32 | 可选 | 通道的预期采样率的提示[可选]。 |
| latency | Uint32 | 可选 | 毫秒为单位的延迟测量[可选]。 |
| inkInputProviderID | string | 可选 | 对InkInputProvider的引用。 |
| inputDeviceID | string | 可选 | 对InputDevice的引用。 |
SensorContext
每个输入设备都有一个SensorContext描述设备的可用传感器。 一个文件可以包含来自两个相同类型设备的Ink数据,它们共享一个上下文。
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| id | string | 可选 | 根据MD5哈希基于MD5哈希的唯一标识符生成方案。 |
| sensorChannelsContext | SensorChannelsContext | 重复 | 用于设备传感器通道的分组上下文。 |
SensorData
SensorData 是用于存储来自墨水传感器的原始数据的核心数据结构。
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| id | string | 可选 | |
| inputContextID | string | 可选 | 通过id引用InputContext。 |
| state | InkState | 可选 | 墨水的状态。 |
| timestamp | uint64 | 可选 | 笔画的第一个样本的时间戳,以毫秒为单位测量。 |
| dataChannels | ChannelData | 重复 | (第一次报告X和Y时的时间)。编码数据列表的数据通道。 |
Stroke
可视路径结构。 Stroke 最简单的形式包含一个或多个 Segments(Catmull-Rom),其中包括一系列位置点,Positions。 除了这些属性之外,数字墨水笔画还包括起始参数和结束参数作为Stroke实体的属性。
| 字段 | 类型 | 标签 | 描述 |
|---|---|---|---|
| id | string | 可选 | 内部ID。 |
| startParameter | float | 可选 | 样条起始参数[0, 1]。 |
| endParameter | float | 可选 | 样条结束参数[0, 1]。 |
| splineX | float | 重复 | X轴的样条值。 |
| splineY | float | 重复 | Y轴的样条值。 |
| splineZ | float | 重复 | Z轴的样条值[用于3D渲染]。 |
| red | float | 重复 | 红色通道的颜色值[0, 1]。 |
| green | float | 重复 | 绿色通道的颜色值[0, 1]。 |
| blue | float | 重复 | 蓝色通道的颜色值[0, 1]。 |
| alpha | float | 重复 | Alpha通道的颜色值[0, 1]。 |
| size | float | 重复 | 笔刷大小。 |
| rotation | float | 重复 | 笔刷旋转z轴。 |
| scaleX | float | 重复 | 笔刷缩放x轴。 |
| scaleY | float | 重复 | 笔刷缩放y轴。 |
| scaleZ | float | 重复 | 笔刷缩放z轴[用于3D渲染]。 |
| offsetX | float | 重复 | 笔刷偏移x轴。 |
| offsetY | float | 重复 | 笔刷偏移y轴。 |
| offsetZ | float | 重复 | 笔刷偏移z轴[用于3D渲染]。 |
| sensorDataOffset | uint32 | 可选 | 原始路径和处理后路径之间映射点的索引。 |
| sensorDataID | string | 可选 | 引用传感器数据。 |
| sensorDataMapping | uint32 | 重复 | Stroke和SensorData索引之间的显式映射,当输入速率非常高且提供了不需要的点时使用。 |
| style | Style | 可选 |