更新记录
1.0.2(2025-12-23) 下载此版本
一、文档补充一下
1.0.1(2025-12-23) 下载此版本
一、文档优化 二、增加直接预览坐标数据组件
1.0.0(2025-12-23) 下载此版本
✨ 新增功能
-
AI 标注功能
- 支持显示 AI 识别结果的矩形标注框
- 支持在图片上绘制标注矩形框
- 支持新增标注(通过弹框输入物种名称和标注ID,然后绘制矩形框)
- 支持删除标注(通过弹框选择要删除的标注)
- 支持连续绘制多个矩形框(输入一次物种名称和标注ID后,可连续绘制多个矩形框)
- 每个矩形框自动生成唯一ID(格式:
原ID_时间戳_随机字符串)
-
标注数据管理
- 支持接收外部传入的标注数据(通过
annotationsprop) - 支持输出标注后的图片和完整的标注数据列表(通过
confirm事件) - 标注数据包含:
id、speciesName、box(坐标字符串)、similarity(置信度)
- 支持接收外部传入的标注数据(通过
-
标注渲染
- 自动在图片上绘制标注矩形框
- 显示物种名称和置信度(百分比)
- 标注文字始终显示在矩形框左上角
- 支持多种颜色区分不同标注
平台兼容性
uni-app(4.07)
| Vue2 | Vue2插件版本 | Vue3 | Vue2插件版本 | Chrome | Safari | app-vue | app-nvue | Android | Android插件版本 | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | 1.0.0 | √ | 1.0.0 | - | - | - | - | 4.4 | 1.0.0 | - | - |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | - | - | - | - | - |
hl-imgEdit
一个基于 uni-app 的图片编辑组件,支持图片标注功能,可以显示、新增、删除 AI 识别结果的矩形标注框。
功能特性
- ✅ 显示 AI 识别结果的矩形标注框
- ✅ 支持新增标注(输入物种名称和标注ID后绘制矩形框)
- ✅ 支持删除标注(通过弹框选择要删除的标注)
- ✅ 支持连续绘制多个矩形框(输入一次信息后可连续绘制)
- ✅ 自动生成唯一标注ID
- ✅ 输出标注后的图片和完整标注数据列表
- ✅ 支持图片缩放、平移操作
- ✅ 支持自定义确认/取消提示文案
安装使用
1. 导入组件
组件位于 uni_modules/hl-imgEdit 目录下,无需额外安装,直接在页面中引入即可。
2. 在页面中使用
<template>
<view>
<button @click="openEditor">打开图片编辑器</button>
<!-- hl-imgEdit 组件 -->
<hl-imgEdit
ref="imgEdit"
:annotations="annotations"
:isAllCanvas="false"
@confirm="handleConfirm"
@cancel="handleCancel"
@error="handleError"
/>
</view>
</template>
<script>
export default {
data() {
return {
annotations: [
{
id: "371893423868739584",
speciesName: "夜鹭",
box: "100,118,210,171",
similarity: 1.0
}
]
}
},
methods: {
openEditor() {
this.$refs.imgEdit.open({
path: '/static/demo.png',
isCancelToast: true,
cancelText: '确定退出编辑吗?',
isConfirmToast: true,
confirmText: '确定完成编辑并保存标注吗?'
})
},
handleConfirm(result) {
console.log('标注后图片:', result.imagePath)
console.log('标注数据:', result.annotations)
},
handleCancel() {
console.log('用户取消了编辑')
},
handleError(err) {
console.error('编辑出错:', err)
}
}
}
</script>
API 文档
Props 属性
| 属性名 | 类型 | 默认值 | 说明 | 平台支持 |
|---|---|---|---|---|
| annotations | Array | [] | AI 标注数据列表 | 全平台 |
| isAllCanvas | Boolean | true | 完成编辑时是否输出整个画布 | 全平台 |
annotations 数据结构
[
{
id: "371893423868739584", // 标注唯一标识
speciesName: "夜鹭", // 物种名称
box: "100,118,210,171", // 矩形坐标,格式为 "x1,y1,x2,y2"
similarity: 1.0 // 识别置信度(0~1,渲染时显示为百分比)
}
]
组件方法
open(options)
打开图片编辑器。
参数说明:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| path | String | 是 | 图片路径 |
| isCancelToast | Boolean | 否 | 是否在取消时显示提示,默认 true |
| cancelText | String | 否 | 取消提示文案,默认 "内容未保存,确定退出吗?" |
| isConfirmToast | Boolean | 否 | 是否在确认时显示提示,默认 true |
| confirmText | String | 否 | 确认提示文案,默认 "确定完成编辑吗?" |
使用示例:
this.$refs.imgEdit.open({
path: '/static/demo.png',
isCancelToast: true,
cancelText: '确定退出编辑吗?',
isConfirmToast: true,
confirmText: '确定完成编辑并保存标注吗?'
})
组件事件
@confirm
确认编辑完成时触发。
事件参数:
{
imagePath: String, // 标注后的图片路径
annotations: Array // 完整的标注数据列表(包含新增、删除后的所有标注)
}
使用示例:
handleConfirm(result) {
console.log('标注后图片:', result.imagePath)
console.log('标注数据:', result.annotations)
// 可以保存图片和标注数据到服务器
}
@cancel
取消编辑时触发。
使用示例:
handleCancel() {
console.log('用户取消了编辑')
}
@error
编辑出错时触发。
事件参数:
Error // 错误对象
使用示例:
handleError(err) {
console.error('编辑出错:', err)
uni.showToast({
title: '编辑出错,请重试',
icon: 'none'
})
}
使用示例
基础示例
最简单的使用方式:
<template>
<view>
<button @click="openEditor">打开图片编辑器</button>
<hl-imgEdit ref="imgEdit" :annotations="annotations" @confirm="handleConfirm" />
</view>
</template>
<script>
export default {
data() {
return {
annotations: []
}
},
methods: {
openEditor() {
this.$refs.imgEdit.open({
path: '/static/demo.png'
})
},
handleConfirm(result) {
console.log('结果:', result)
}
}
}
</script>
完整示例(Vue 3)
<template>
<view class="page-container">
<view class="button-group">
<button class="btn-primary" @click="openEditor">打开图片编辑器</button>
<button class="btn-secondary" @click="resetData">重置为初始数据</button>
</view>
<view class="info-section" v-if="resultImagePath">
<view class="info-title">处理结果</view>
<view class="result-item">
<text class="label">标注后图片:</text>
<image :src="resultImagePath" mode="aspectFit" class="result-image"></image>
</view>
<view class="result-item">
<text class="label">标注数据({{ resultAnnotations.length }} 条):</text>
<scroll-view class="annotation-list" scroll-y>
<view
class="annotation-item"
v-for="(item, index) in resultAnnotations"
:key="item.id || index"
>
<text class="annotation-text">
{{ index + 1 }}. {{ item.speciesName }} ({{ (item.similarity * 100).toFixed(2) }}%) - ID: {{ item.id }}
</text>
<text class="annotation-box">坐标: {{ item.box }}</text>
</view>
</scroll-view>
</view>
</view>
<hl-imgEdit
ref="imgEdit"
:annotations="annotations"
:isAllCanvas="false"
@confirm="handleConfirm"
@cancel="handleCancel"
@error="handleError"
/>
</view>
</template>
<script setup>
import { ref, onMounted, getCurrentInstance, nextTick } from 'vue'
import annotationData from '@/static/data.json'
const instance = getCurrentInstance()
// 标注数据
const annotations = ref([])
// 处理结果
const resultImagePath = ref('')
const resultAnnotations = ref([])
// 组件引用
const imgEdit = ref(null)
// 页面挂载后加载测试数据
onMounted(() => {
annotations.value = JSON.parse(JSON.stringify(annotationData))
})
// 获取组件实例
function getImgEditInstance() {
if (imgEdit.value && typeof imgEdit.value.open === 'function') {
return imgEdit.value
}
return null
}
// 打开编辑器
const openEditor = async () => {
await nextTick()
const editor = getImgEditInstance()
if (!editor) {
uni.showToast({
title: '组件未加载完成,请稍后再试',
icon: 'none'
})
return
}
editor.open({
path: '/static/demo.png',
isCancelToast: true,
cancelText: '确定退出编辑吗?',
isConfirmToast: true,
confirmText: '确定完成编辑并保存标注吗?'
})
}
// 重置为初始数据
const resetData = () => {
annotations.value = JSON.parse(JSON.stringify(annotationData))
resultImagePath.value = ''
resultAnnotations.value = []
uni.showToast({
title: '已重置为初始数据',
icon: 'success'
})
}
// 确认回调
const handleConfirm = (result) => {
if (result && result.imagePath) {
resultImagePath.value = result.imagePath
resultAnnotations.value = result.annotations || []
annotations.value = result.annotations || []
uni.showToast({
title: `已保存 ${resultAnnotations.value.length} 条标注`,
icon: 'success',
duration: 2000
})
}
}
// 取消回调
const handleCancel = () => {
console.log('用户取消了编辑')
}
// 错误回调
const handleError = (err) => {
console.error('编辑出错:', err)
uni.showToast({
title: '编辑出错,请重试',
icon: 'none'
})
}
</script>
新增标注流程
- 点击"新增标注"按钮
- 在弹框中输入物种名称和标注ID
- 点击"确认"后,可以连续绘制多个矩形框
- 每个矩形框会自动生成唯一的ID(格式:
原ID_时间戳_随机字符串) - 所有矩形框使用相同的物种名称和基础标注ID
删除标注流程
- 点击"删除标注"按钮(仅在有标注时显示)
- 在弹框中选择要删除的物种
- 点击"确认"删除该物种的所有标注
注意事项
1. 标注数据结构
标注数据必须符合以下格式:
{
id: String, // 标注唯一标识(必填)
speciesName: String, // 物种名称(必填)
box: String, // 矩形坐标,格式为 "x1,y1,x2,y2"(必填)
similarity: Number // 识别置信度,0~1(必填)
}
2. 坐标格式
box 字段必须是字符串格式,坐标之间用逗号分隔:
// ✅ 正确
box: "100,118,210,171"
// ❌ 错误
box: [100, 118, 210, 171] // 不能是数组
box: "100, 118, 210, 171" // 坐标之间不能有空格
3. 连续绘制标注
- 输入一次物种名称和标注ID后,可以连续绘制多个矩形框
- 每个矩形框会自动生成唯一的ID(基于输入的标注ID加上时间戳和随机字符串)
- 绘制完成后不会清空输入信息,可以继续绘制
4. 图片路径
- 支持相对路径(如
/static/demo.png) - 支持网络图片(需要配置域名白名单)
- 支持本地临时文件路径
5. 平台支持
| 平台 | 支持状态 | 说明 |
|---|---|---|
| App | ✅ | 完全支持 |
6. 性能优化
- 标注数量较多时,建议使用
isAllCanvas: false以优化性能 - 图片较大时,建议先压缩图片再传入组件
7. 常见问题
Q: 标注不显示怎么办?
A: 请检查:
annotations数据格式是否正确box坐标是否在图片范围内- 图片路径是否正确
Q: 保存的图片不包含原始图片?
A: 请确保传入的 path 参数正确,并且图片可以正常加载。
Q: 如何获取标注后的图片和标注数据?
A: 在 @confirm 事件回调中获取:
handleConfirm(result) {
const imagePath = result.imagePath // 标注后的图片路径
const annotations = result.annotations // 完整的标注数据列表
}
Q: 可以修改标注的样式吗?
A: 目前标注样式是固定的,包括矩形框颜色、文字样式等。如需自定义样式,需要修改组件源码。

收藏人数:
下载插件并导入HBuilderX
下载示例项目ZIP
赞赏(0)
下载 271
赞赏 2
下载 12493319
赞赏 1830
赞赏
京公网安备:11010802035340号