news 2026/6/14 21:30:29

Annotorious入门教程:图片注释工具

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Annotorious入门教程:图片注释工具

本文简介

最近有工友问我前端怎么给图片做标注。使用Fabric.js或者Konva.js等库确实可以实现,但我又好奇有没有专门做图片标注的工具呢?

在网上搜了一下发现Annotorious可以实现这个功能。Annotorious提供了图片注释和标注功能,而且用法很简单。


本文分为 【快速入门】和【API讲解】两部分。

【快速入门】部分包含Annotorious的安装、使用、导入导出的讲解。这几点应该是项目中比较核心的流程,给希望快速入门的工友提供一丢丢帮助。

【API讲解】这部分主要讲一下我认为比较常用的功能。注意:是“我认为”。



快速入门

快速入门部分会讲解Annotorious的安装、使用、导入和导出数据功能。


安装 Annotorious

CDN

<!-- 引入样式 --><linkrel="stylesheet"href="https://cdn.jsdelivr.net/npm/@recogito/annotorious@2.7.10/dist/annotorious.min.css"><!-- 引入js --><scriptsrc="https://cdn.jsdelivr.net/npm/@recogito/annotorious@2.7.10/dist/annotorious.min.js"></script>

你可以把这两份文件下载到自己的项目里再引入。


NPM

用以下命令安装Annotorious

npm install @recogito/annotorious

然后在项目中引入

import{Annotorious}from'@recogito/annotorious'import'@recogito/annotorious/dist/annotorious.min.css'

使用 annotorious

Annotorious安装到项目后就可以使用了。

Annotorious的用法很简单,只需做以下2步:

  1. 在html部分插入图片
  2. 初始化Annotorious,并绑定图片元素(元素的ID或者元素本身)


CDNNPM在初始化时的用法稍微有点不同。

CDN

<imgsrc="./img.jpg"id="my-image"/><script>letanno=Annotorious.init({image:'my-image'// 元素ID})</script>

使用CDN的方式引入Annotorious,在初始化时要Annotorious.init这样写。


NPM

<imgsrc="./img.jpg"id="my-image"/><script>constanno=newAnnotorious({image:document.getElementById('my-image')// 元素本身})</script>

使用NPM的方式引入Annotorious在初始化时需要new Annotorious这样写。


注意:在Annotorious初始化代码最好放在你所使用的框架的页面加载完成后的生命周期函数里!


导出数据 getAnnotations()

如果你需要将图片上的标注保存到服务器,就需要把数据导出。

所用到的方法是getAnnotations()

<buttononclick="save()">保存</button><imgsrc="./44.jpg"id="img"/><script>letanno=nullonload=function(){anno=Annotorious.init({image:'img'})}functionsave(){letres=anno.getAnnotations()console.log(res)}</script>

导入数据 loadAnnotations(url)

Annotorious可以通过loadAnnotations()方法加载数据。

loadAnnotations(url)支持传入一个URL参数,这个URL所指的是数据文件地址。

比如我在本地创建一个data.json文件,文件内容是使用前面讲到的getAnnotations()方法导出的数据,我的数据内容如下:

[{"@context":"http://www.w3.org/ns/anno.jsonld","type":"Annotation","body":[{"type":"TextualBody","value":"1","purpose":"commenting"}],"target":{"source":"http://127.0.0.1:5500/44.jpg","selector":{"type":"FragmentSelector","conformsTo":"http://www.w3.org/TR/media-frags/","value":"xywh=pixel:100,100,500,300"}},"id":"#cabe2e71-b19f-4499-80c6-235882fd50ba"}]

在本地测试时,我使用了本地服务器把data.json管理起来,在浏览器可以通过http://127.0.0.1:5500/data.json访问到该文件。

然后再使用loadAnnotations(url)方法把数据渲染出来即可。

<buttononclick="load()">加载</button><imgsrc="./44.jpg"id="img"/><script>letanno=nullonload=function(){anno=Annotorious.init({image:'img'})}functionload(){anno.loadAnnotations("http://127.0.0.1:5500/data.json")}</script>

点击加载按钮后,图片上就会出现一个选框,点击选框可以看到数据已经成功加载出来。


添加数据 addAnnotation()

但在实际项目中,后台不一定会给前端返回一个文件地址,后台可能会直接返回一个json数据。

这时候如果使用loadAnnotations()方法加载json数据是行不通的,要通过遍历读取数据中心的data里的数据,然后调用addAnnotation()方法将元素添加到页面。


我使用json-server简单的在本地搭建一个服务器给前端访问对应的资源,前端用axios请求资源。

<buttononclick="load()">加载</button><imgsrc="./44.jpg"id="img"/><script>letanno=nullonload=function(){anno=Annotorious.init({image:'img'})}functionload(){axios.get('http://localhost:3000/anno').then(res=>{res.data.data.forEach(item=>{anno.addAnnotation(item)})})}</script>

很久之前写过一篇 《『前端必备』本地数据接口 —— json-server 从入门到膨胀》 文章介绍json-server的基础用法,有兴趣的工友可以去瞧瞧。



API讲解

这部分主要讲一些我关注到的功能,如果想全面了解Annotorious可以查看文档。


汉化 locale

Annotorious是根据浏览器的设置来确定使用哪种语言。


如果需要修改Annotorious使用的语言,可以在初始化时配置一下locale字段。

比如配置简体中文可以用zh-CN,配置繁体中文可以用zh-TW

<imgsrc="./img.jpg"id="my-image"/><script>letanno=Annotorious.init({image:'my-image',locale:'zh-CN'// 修改语言})</script>

自定义提示文本 messages

如果想自定义按钮或者输入框的提示文本可以配置messages

<imgsrc="./img.jpg"id="my-image"/><script>// 创建一个包含自定义消息的对象varcustomMessages={"Add a comment...":"评论评论","Add a reply...":"回复两句","Add tag...":"这是标签啊","Cancel":"取消","Close":"关闭","Edit":"编辑~","Delete":"删除❌","Ok":"确定"}letanno=Annotorious.init({image:'my-image',messages:customMessages// 自定义消息内容})</script>

如果同时配置了localemessages,会优先使用message的值。


空注释 allowEmpty

默认情况下,如果框选后没输入标签或者评论就按确定是不会保存选框的。

如果想保存空选框,可以将allowEmpty设置为true

<imgsrc="./img.jpg"id="my-image"/><script>letanno=Annotorious.init({image:'my-image',allowEmpty:true// 允许空注释})</script>

框选辅助线 crosshair

有些鼠标指针可能并不是那么标准,会影响你框选的准确性。

如果需要非常准确去框选,可以开启辅助线功能,只需将crosshair设置为true即可。

<imgsrc="./img.jpg"id="my-image"/><script>letanno=Annotorious.init({image:'my-image',crosshair:true// 开启辅助线})</script>

只读 readOnly

如果不打算提供框选、添加和删除信息的操作给用户,可以将readOnly设置为true

<imgsrc="./img.jpg"id="my-image"/><script>letanno=Annotorious.init({image:'my-image',readOnly:true// 只读模式})</script>

禁止编辑 disableEditor

如果只需要画框框,不需要写注释,可以将disableEditorallowEmpty同时设置为true

<imgsrc="./img.jpg"id="my-image"/><script>letanno=Annotorious.init({image:'my-image',allowEmpty:true,// 允许空注释disableEditor:true// 禁用编辑})</script>

为什么要同时将allowEmpty设为true

因为如果你不允许注释为空的话,当你点击空白处时选框就会消失。


禁止选中选框 disableSelect

disableSelect设置为true后,画布上的选框就无法再次选中了。

<imgsrc="./img.jpg"id="my-image"/><script>letanno=Annotorious.init({image:'my-image',disableSelect:true// 禁止选中选框})</script>

虽然还没想到有什么引用场景,但还是打算记录一下。


手柄半径 handleRadius

箭头所指的就是手柄。

手柄的默认半径是6。如果需要修改手柄半径可以设置handleRadius属性。

<imgsrc="./img.jpg"id="my-image"/><script>letanno=Annotorious.init({image:'my-image',handleRadius:20// 设置手柄半径})</script>

自定义选框样式

Annotorious的选框和编辑器都是可以使用css设置样式的。

选框部分使用了SVG,编辑器部分直接用了HTML元素。

SVG不了解的工友可以阅读 《SVG专栏》。


回到Annotorious,官方也有给出一个自定义样式的案例 《Customizing Visual Appearance》。

<style>/* 选框 *//* 隐藏外部形状-对于这种风格,我们只需要一个 */svg.a9s-annotationlayer .a9s-selection .a9s-outer, svg.a9s-annotationlayer .a9s-annotation .a9s-outer{display:none;}svg.a9s-annotationlayer .a9s-handle .a9s-handle-outer{display:none;}/* 虚线边框 */svg.a9s-annotationlayer .a9s-selection .a9s-inner, svg.a9s-annotationlayer .a9s-annotation .a9s-inner{stroke-width:4;stroke:white;stroke-dasharray:5;}/* 选中时的填充色 */svg.a9s-annotationlayer .a9s-annotation.editable:hover .a9s-inner{fill:transparent;}/* 手柄颜色 */svg.a9s-annotationlayer .a9s-handle .a9s-handle-inner{fill:white;stroke:white;}/* 选中选框时,遮罩层颜色 */svg.a9s-annotationlayer .a9s-selection-mask{fill:rgba(0,0,0,0.6);}/* 编辑器 *//* 容器 */.r6o-editor .r6o-editor-inner{box-sizing:border-box;padding:10px;border-radius:6px;background:#F4F2DE;}/* 箭头 */.r6o-editor .r6o-arrow:after{background-color:#F4F2DE;}/* 编辑器 */.r6o-widget.comment.editable, .r6o-widget.r6o-tag{background-color:#EEE3CB;}.r6o-widget.comment{background-color:#D7C0AE;}.r6o-editor .r6o-editor-inner .r6o-widget{border-bottom-color:#7C9D96;}.r6o-editor .r6o-editor-inner .r6o-widget.r6o-tag{border-bottom:none;}/* 按钮 */.r6o-editor .r6o-btn{border-radius:100px;background-color:#7C9D96;border-color:#7C9D96;color:#fff;}/* 线框按钮 */.r6o-editor .r6o-btn.outline{color:#7C9D96;background-color:transparent;}</style><imgsrc="./img.jpg"id="my-image"/><script>letanno=Annotorious.init({image:'my-image',locale:'zh-CN'// 修改语言})</script>

上面这份代码选框的样式是从Annotorious官网教程搬过来的。

编辑器的样式我随便配了一下,工友们也可以打开浏览器控制台看Elements面板的HTML代码,根据结构去修改样式即可。


筛选功能

输入时需要快速添加预选项时,可以这样配置:

<imgsrc="./img.jpg"id="my-image"/><script>letanno=Annotorious.init({image:'my-image',widgets:['COMMENT',{widget:'TAG',vocabulary:['雷猴','鲨鱼辣椒','蝎子莱莱']}]})</script>

多边形选框

使用setDrawingTool(toolName)方法可以设置不同的绘制工具。

如果需要讲选框设置成多边形,可以传入'polygon'

<imgsrc="./img.jpg"id="my-image"/><script>letanno=Annotorious.init({image:'my-image'})anno.setDrawingTool("polygon")</script>

想要知道当前有哪些绘图工具,可以使用anno.listDrawingTools()方法查看

<imgsrc="./img.jpg"id="my-image"/><script>letanno=Annotorious.init({image:'my-image'})consttoolNames=anno.listDrawingTools()console.log(toolNames)</script>

其他

除了上面介绍到的API外,Annotorious还有很多玩法的,比如删除指定注释、清空所有注释等。

详情请看 《annotorious API文档》



插件

Annotorious也有一些好玩的插件,有兴趣的可以看看 《Annotorious 插件推荐》。

Annotorious 可快速实现图片标注,支持标注数据导入导出与样式自定义,落地时需考虑组件复用、快速部署的工程效率问题。试试RollCode 低代码平台,轻松搞定私有化部署、自定义组件、静态页面发布(SSG + SEO)。


点赞 + 关注 + 收藏 = 学会了

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 14:41:47

(9-2-02)电源管理与能源系统:能耗分析与功率管理(2)高峰功耗控制+ 电源分配架构

9.2.2 高峰功耗控制 高峰功耗是人形机器人动力系统面临的核心挑战之一&#xff0c;特指机器人在跳跃、快速转向、应急制动、负重突变等动态动作中&#xff0c;关节驱动电机、液压/气动执行器等负载产生的瞬时高功率需求&#xff0c;其峰值通常可达电池持续输出功率的2-5倍。若…

作者头像 李华
网站建设 2026/6/15 14:42:57

专科生也能用!学生热捧的AI论文软件 —— 千笔AI

你是否曾为论文选题发愁&#xff1f;是否在写到一半时突然卡文&#xff0c;毫无头绪&#xff1f;又或是反复修改却总达不到老师要求&#xff1f;对于专科生来说&#xff0c;论文写作不仅是学术任务&#xff0c;更是一场心理挑战。面对查重率、格式规范、文献查找等难题&#xf…

作者头像 李华
网站建设 2026/6/14 2:11:15

一文读懂VR/AR/MR:小白也能分清的虚实交互技术

一文读懂 VR / AR / MR&#xff08;附 XR&#xff09;——小白也能分清的虚实交互技术&#xff08;2026 年最新视角&#xff09; 2026 年了&#xff0c;头显设备已经从“玩具”变成了部分人的生产力工具和娱乐刚需&#xff0c;但很多人一听到 VR、AR、MR、XR 还是会懵。 其实它…

作者头像 李华
网站建设 2026/6/15 12:18:45

根据Excel 模板生成excel(java)

重阳&#xff0c;需求很常见&#xff1a;根据一个已设计好的 Excel 模板&#xff08;含样式、公式、合并单元格、表头、页眉页脚等&#xff09;&#xff0c;往里面填充动态数据&#xff0c;然后生成新的 Excel 文件。 2026 年主流的三种方案对比&#xff08;基于当前社区使用情…

作者头像 李华
网站建设 2026/6/15 13:18:45

降重≠换词!虎贲等考 AI:双重净化 AIGC 痕迹,查重率直降 25%+

“论文降重改到崩溃&#xff0c;重复率还是飙到 30%”“AI 写的初稿被导师标记‘机器感过重’”“降重后语句不通&#xff0c;学术逻辑全乱”—— 这是当下毕业生写论文时最头疼的两大痛点。单纯的同义词替换早已过时&#xff0c;既过不了查重关&#xff0c;还可能因 AIGC 痕迹…

作者头像 李华