图片标注编辑平台搭建系列教程(7)——标注平台架构设计

框架

标注平台核心是渲染+编辑。渲染由fabric支持,编辑由ID支持。

渲染

首先,我们基于fabric.util.createClass方法,继承出新的类:NPoint、NPolyline、NPolygon、NText。

  1. NPoint继承fabric.Circle
  2. NPolyline继承fabric.Polyline
  3. NPolygon继承fabric.Path
  4. NRectangle继承fabric.Rect
  5. NText继承fabric.Text

有人可能问,NPolygon为什么继承fabric.Path?这是因为fabric.Polygon继承自fabric.Polyline,所以不支持孔洞(hole),而fabric.Path可以解决这个问题。后续可以开一期专门讲具体实现。

按照前几章的内容,有了这五个类,我们可以对其渲染进行自定义扩展,例如带箭头的线,有填充色的面等等。

编辑

Entity

标注数据在标注平台中解析为Entity(openstreetmap的数据格式,当然这种格式自定义即可,不一定要用这种)。Entity是抽象类,Node、Way、Relation继承自Entity。

entity的基本格式如下:

{
    id: 'n-1', // id
    geometry: {...}, // 几何
    type: 'node', // 类型
    tags: {...}, // 属性
    members: [{...}], // 关系
    v: 0 // 版本号
}

对于标注平台而言,id、geometry和tags应该是我们重点关注的内容。特别是tags,将要存放我们标注的信息,无论是图像分割还是图像标注。

Graph

我们知道,ID中有个核心类叫作Graph,这是用于存储数据的。每一次编辑,都会有一版新的Graph推入栈中,从而实现撤销、重做功能。

如何往Graph中插入数据?需要借助History类。

History

History是管理Graph的类,封装了各种操作Graph的方法,例如pop、perform、replace、merge、reset等。

比如我们加载了一些存量的标注数据,我们将其解析为entity。然后,我们可以通过history.merge方法,将存量数据加载到baseGraph中(第一版Graph)。

在后续的编辑操作中,我们仅需要通过history.perform或者history.replace这两个方法即可。前者表示本次编辑操作需要存入一个新的Graph,后者表示本次编辑操作存入当前Graph即可。

撤销调用history.undo,将当前指针前移一版Graph,重做调用history.redo,将当前指针后移一版Graph。

所有History修改Graph的方法,都需要传入一个方法数组,这种方法称为action。

Action

action的输入和输出都是Graph,我们在方法内部写修改Graph的具体实现。

action = (graph) => {
    // 修改graph 
    return graph;
}

一般情况下,在action内部,我们会修改或者新增一些Entity,然后通过 graph = graph.replace(entity)的方法,将数据存入Graph。而修改或者新增Entity的方法,最终会调用Entity基类里的方法update,通过拷贝原始entity的属性值,并用新的值覆盖,创建一个新的Entity实例。

那么,标注平台集成那么多编辑工具,有没有什么设计模式可以抽象出一些交互模式?

答案是有的。ID提供了更加抽象的类mode和behavior来解决交互模式问题。

Mode

在ID中,同一个时间点只能有一种mode,例如当前处于浏览模式、选中模式、绘制模式等等。当你处于一种模式中,你就只能执行当前模式下所包含的行为(behavior)。

如果要进入另一个mode,需要先退出当前mode(exit),卸载bahvior(off),然后才会进入新mode(enter),并且注册hehavior(add),这样确保交互模式的统一和切换。所有工具都可以抽象(封装)为一个mode+若干behavior的组合模式。这样,当你要使用某个编辑工具,只需要进入这个工具的mode即可。你的实际交互逻辑,都写在behavior中。

Behavior

何为behavior?本质上就是一种固定的行为,例如,画线、画点、画面、画矩形、插形点等等。behavior有什么能力呢?你可以在behavior内做任何和你当前mode有关的行为,例如,绑定某个快捷键,监听某个事件等等。需要注意的是,任何监听,都应该在卸载behavior时注销,否则监听事件可能会造成内存泄漏。

对于标注平台,我们需要的工具有,画点、画线、画面、画矩形。而这些绘制工具的实现逻辑,也恰恰是标注平台的基础。一个好的编辑工具,不仅需要具备兼容性,还要可扩展。同时需要考虑标注过程可能出现的问题,并给予解决。举个最简单的例子,用户在绘制线的过程中,如果某一个点画错了,需要支持撤销,如何实现?简单来说,抛开渲染 ,你需要在画线的behavior中监听history的undo事件。

总结

整体而言,fabric负责搞定一切渲染,简单样式足以。而强大的地图编辑器ID,用于图片编辑,简直是小菜一碟。以上,整体框架敲定。

预告

下一章,我们讲讲如何为way、node扩展出fabric渲染方法。

  • 25
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HouGISer

HouGiser需要你的鼓励~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值