添加图像标注:用画笔、箭头、圆形标注图片
学完你能做什么
- ✅ 在计划评审或代码评审中附加图像
- ✅ 使用画笔工具自由绘制标注
- ✅ 使用箭头工具标注重点区域
- ✅ 使用圆形工具圈选区域
- ✅ 调整标注颜色和笔触大小
- ✅ 使用快捷键快速切换工具和操作
你现在的困境
问题 1:评审 UI 设计稿或流程图时,文字描述不够直观,需要圈出问题区域。
问题 2:想给代码评审添加截图注释,但只能用文字说明"这里有问题",无法在图上直接标记。
问题 3:收到团队分享的图片链接,想快速标注反馈,但不想下载到本地用其他工具处理。
Plannotator 能帮你:
- 直接在浏览器中标注图片,无需下载到本地
- 画笔、箭头、圆形三种工具,覆盖所有标注场景
- 五种颜色和五种笔触大小,灵活调整标注效果
- 快捷键操作,提升标注效率
什么时候用这一招
使用场景:
- 评审 UI 设计稿、流程图、架构图时需要标注问题
- 代码评审中需要截图并标注代码问题
- 分享带标注的图片给团队成员
- 需要在图片上圈选重点区域或添加箭头指引
🎒 开始前的准备
核心思路
图像标注的三种工具:
| 工具 | 图标 | 快捷键 | 用途 |
|---|---|---|---|
| 画笔 | 🖊️ | 1 | 自由绘制,适合手写注释、圈选任意形状 |
| 箭头 | ➡️ | 2 | 标注重点区域或指示方向,适合点对点标注 |
| 圆形 | ⭕ | 3 | 圈选区域,适合突出显示某个元素 |
工作流程:
上传图片 → 选择工具 → 调整颜色和大小 → 在图片上绘制 → 保存跟我做
第 1 步:打开计划评审或代码评审页面
为什么 Plannotator 的图像标注功能集成在计划评审和代码评审中。
操作
- 启动计划评审(Claude Code 触发或 OpenCode 调用 submit_plan)
- 或运行
/plannotator-review命令启动代码评审
你应该看到:
- 浏览器打开评审页面
- 右上角有「Upload」或「附件」按钮
第 2 步:上传图像
为什么 需要先上传图片才能进行标注。
操作
- 点击页面右上角的「Upload」或「附件」按钮
- 选择要标注的图片(支持 PNG、JPEG、WebP 格式)
- 图片上传后会显示在注释列表中
你应该看到:
- 图片缩略图出现在注释区域
- 点击缩略图可以打开标注编辑器
图片来源
你可以通过以下方式获取图片:
- 截图并粘贴(Ctrl+V / Cmd+V)
- 从本地文件选择
- 拖拽图片到页面
第 3 步:打开图像标注编辑器
为什么 标注编辑器提供绘图工具和颜色选择。
操作
- 点击已上传的图片缩略图
- 图像标注编辑器会在弹窗中打开
你应该看到:
- 图片居中显示
- 顶部有一排工具栏
- 工具栏从左到右:工具选择、笔触大小、颜色选择、撤销、清空、保存
第 4 步:使用画笔工具自由绘制
为什么 画笔工具适合手写注释或圈选任意形状。
操作
- 确保选中了画笔工具(🖊️ 图标,默认选中)
- 按下鼠标左键,在图片上绘制
- 松开鼠标完成绘制
你应该看到:
- 鼠标移动时跟随的线条轨迹
- 松开鼠标后,绘制的形状固定在图片上
画笔特点
- 使用 perfect-freehand 库实现平滑的手绘效果
- 支持压力感应(如果你的设备支持)
- 笔触越粗,线条越平滑
第 5 步:使用箭头工具标注重点
为什么 箭头适合点对点标注,明确指出问题位置。
操作
- 点击箭头工具(➡️ 图标)或按快捷键
2 - 在图片上点击确定箭头起点
- 拖动到目标位置,松开鼠标完成箭头绘制
你应该看到:
- 从起点到终点的一条直线
- 终点有一个箭头,指向目标位置
箭头绘制技巧
- 起点是箭头尾部,终点是箭头头部
- 拖动过程中可以实时预览箭头方向
- 适合标注"这里有问题"或"需要修改这里"等场景
第 6 步:使用圆形工具圈选区域
为什么 圆形适合突出显示某个元素,圈选范围清晰。
操作
- 点击圆形工具(⭕ 图标)或按快捷键
3 - 在图片上点击确定圆形的一条边
- 拖动到对边,松开鼠标完成圆形绘制
你应该看到:
- 一个圆形,起始点到终止点的连线为直径
- 圆形中心是两点连线的中点
圆形绘制原理
圆形工具从边缘到边缘绘制:
- 第 1 次点击:圆的某一条边
- 拖动:确定圆的直径
- 松开:绘制完成圆
源码实现(utils.ts:95-124):
// 中心是起点和终点的中点
const cx = (x1 + x2) / 2;
const cy = (y1 + y2) / 2;
// 半径是两点距离的一半
const radius = Math.hypot(x2 - x1, y2 - y1) / 2;第 7 步:调整标注颜色
为什么 不同颜色可以区分不同类型的标注(如红色表示错误,绿色表示建议)。
操作
- 在工具栏中点击颜色圆点
- 可选颜色:红色、黄色、绿色、蓝色、白色
你应该看到:
- 当前选中的颜色圆点会放大显示
- 所有新绘制的标注都使用当前颜色
颜色使用建议
- 红色:错误、问题、需要删除的内容
- 黄色:警告、注意、需要确认的地方
- 绿色:建议、优化、改进意见
- 蓝色:补充说明、备注
- 白色:适用于深色背景的图片
第 8 步:调整笔触大小
为什么 不同大小的笔触适合不同的标注场景。
操作
- 点击工具栏中的
-或+按钮 - 或观察当前笔触大小预览(一个圆点)
你应该看到:
- 笔触大小可选:3、6、10、16、24
- 工具栏中间显示当前笔触大小的预览圆点
笔触大小建议
- 3:精确标注小元素(如按钮、图标)
- 6:常规标注(默认值)
- 10:粗线条标注,适合圈选较大区域
- 16:非常粗的标注,适合强调重点
- 24:最大笔触,适合突出显示超大区域
第 9 步:撤销和清空
为什么 标注过程中难免出错,需要撤销或重新开始。
操作
- 撤销上一步:点击撤销图标(↩️)或按
Cmd+Z/Ctrl+Z - 清空所有标注:点击清空图标(❌)
你应该看到:
- 撤销:最后一次绘制的标注消失
- 清空:所有标注被移除,恢复到原始图片
清空提示
清空操作不可撤销,请谨慎使用。建议先用撤销逐步回退。
第 10 步:保存标注
为什么 保存标注后,图片会被合并到注释中,可以在评审中查看。
操作
- 点击工具栏右侧的保存图标(✅)
- 或按
Esc或Enter键 - 或点击弹窗外部区域
你应该看到:
- 弹窗关闭
- 图片缩略图更新为标注后的版本
- 图片已附加到当前注释中
保存机制
- 如果没有绘制任何标注,直接保存原始图片
- 如果有标注,将原始图片和标注合并为一张新图片
- 合并后的图片以 PNG 格式保存,保持高质量
检查点 ✅
验证你的学习成果:
- [ ] 能成功上传图片到评审页面
- [ ] 能使用画笔、箭头、圆形三种工具绘制标注
- [ ] 能调整标注颜色和笔触大小
- [ ] 能使用快捷键(1/2/3、Cmd+Z、Esc)快速操作
- [ ] 能撤销错误的标注
- [ ] 能保存标注后的图片
踩坑提醒
问题 1:箭头方向反了
现象:箭头指向了错误的方向。
原因:箭头工具从起点(尾部)到终点(头部)绘制。
解决:
- 重新绘制,确保起点是箭头尾部,终点是箭头头部
- 如果已绘制,撤销后重画
问题 2:圆形位置不对
现象:圆形没有圈选到目标区域。
原因:圆形工具从边缘到边缘绘制,中心是两点中点。
解决:
- 第一次点击在目标区域的边缘
- 拖动到对边,确保目标区域在圆内
- 调整时可以撤销重画
问题 3:笔触太粗或太细
现象:标注效果不理想。
原因:笔触大小不适合当前场景。
解决:
- 使用工具栏的
-或+按钮调整笔触大小 - 小元素用 3-6,大区域用 10-24
问题 4:颜色看不清
现象:在深色背景上使用黑色笔触,看不清标注。
原因:颜色选择不当。
解决:
- 深色背景使用白色或黄色
- 浅色背景使用红色、绿色或蓝色
快捷键速查
| 快捷键 | 功能 |
|---|---|
1 | 切换到画笔工具 |
2 | 切换到箭头工具 |
3 | 切换到圆形工具 |
Cmd+Z / Ctrl+Z | 撤销上一步 |
Esc / Enter | 保存标注 |
本课小结
本课你学会了:
- 上传图片:通过上传按钮或粘贴到评审页面
- 三种标注工具:
- 画笔(1):自由绘制,适合手写注释
- 箭头(2):点对点标注,适合指示重点
- 圆形(3):圈选区域,适合突出显示
- 调整标注样式:5 种颜色、5 种笔触大小
- 撤销和清空:修正错误的标注
- 保存标注:将标注合并到图片中
下一课预告
下一课我们学习 代码评审基础。
你会学到:
- 如何使用 /plannotator-review 命令评审 git diff
- 在 side-by-side 和 unified 视图间切换
- 点击行号选择代码范围
- 添加行级注释(comment/suggestion/concern)
- 切换不同的 diff 类型
- 将反馈发送给 AI Agent
附录:源码参考
点击展开查看源码位置
更新时间:2026-01-24
| 功能 | 文件路径 | 行号 |
|---|---|---|
| 工具类型定义 | packages/ui/components/ImageAnnotator/types.ts | 1-40 |
| 渲染函数 | packages/ui/components/ImageAnnotator/utils.ts | 1-148 |
| 主组件 | packages/ui/components/ImageAnnotator/index.tsx | 1-233 |
| 工具栏组件 | packages/ui/components/ImageAnnotator/Toolbar.tsx | 1-219 |
| Annotation 接口 | packages/ui/types.ts | 11-33 |
关键类型:
Tool(工具类型):
export type Tool = 'pen' | 'arrow' | 'circle';Point(坐标点):
export interface Point {
x: number;
y: number;
pressure?: number;
}Stroke(笔触):
export interface Stroke {
id: string;
tool: Tool;
points: Point[];
color: string;
size: number;
}AnnotatorState(标注器状态):
export interface AnnotatorState {
tool: Tool;
color: string;
strokeSize: number;
strokes: Stroke[];
currentStroke: Stroke | null;
}COLORS(颜色数组):
export const COLORS = [
'#ef4444', // red
'#eab308', // yellow
'#22c55e', // green
'#3b82f6', // blue
'#ffffff', // white
] as const;STROKE_SIZES(笔触大小):
const STROKE_SIZES = [3, 6, 10, 16, 24];关键函数:
renderPenStroke()(渲染画笔笔触):
- 使用 perfect-freehand 库实现平滑手绘效果
- 支持压力感应(pressure 字段)
renderArrow()(渲染箭头):
- 从起点绘制直线到终点
- 在终点绘制箭头头部
renderCircle()(渲染圆形):
- 计算两点中点作为圆心
- 计算两点距离的一半作为半径
renderStroke()(根据工具类型渲染):
- 根据 tool 字段调用对应的渲染函数
- 支持缩放(scale 参数)
Annotation.imagePaths(附加图片字段):
export interface Annotation {
// ...
imagePaths?: string[]; // Attached images (local paths or URLs)
}快捷键处理(index.tsx:33-59):
// 1/2/3 to switch tools
if (e.key === '1') setState(s => ({ ...s, tool: 'pen' }));
if (e.key === '2') setState(s => ({ ...s, tool: 'arrow' }));
if (e.key === '3') setState(s => ({ ...s, tool: 'circle' }));
// Cmd+Z to undo
if ((e.metaKey || e.ctrlKey) && e.key === 'z') {
e.preventDefault();
handleUndo();
}