Skip to content

Commit 843bfce

Browse files
committed
docs(v0.7.7): 结构图捕获持久化规划(REQ-182~187 登记)
1 parent 4edb5db commit 843bfce

3 files changed

Lines changed: 244 additions & 0 deletions

File tree

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# 非线性结构图像捕获与持久化(结构图)+ v0.7.7 修复项——头脑风暴与设计规格
2+
3+
**状态**: 已裁决(2026-08-20 用户头脑风暴:方案 A+ 批量+屏内选优;混合触发;会话内图库;两个修复项并入)
4+
**版本**: v0.7.7(0.7 下一个小版本,独立发布,不与 v0.8.0 AI 合并)
5+
**关联**: 版面分析(REQ-047,layout_analyzer.rs 规则版)· 屏卡体系(REQ-155~161,[ADR-015](../../adr/ADR-015-screen-cards-ocr.md))· 三层图存储(REQ-051/110,image_store)· [ADR-010](../../adr/ADR-010-gap-filling-ai.md)(图语义"必须理解才能还原"→ 本版用"图像即产物"兜底)· REQ-056/058(AI 语义重建 V1.0)
6+
7+
---
8+
9+
## 一、问题与动机
10+
11+
版面分析(v0.5.0)已能把帧区域分类为 text/table/formula/code/image/unknown,但**非线性文本结构**(含义依赖二维排布、线性 OCR 必然失真的内容)缺少"图像级持久化"闭环:
12+
13+
| 结构类型 | 现状 | 缺口 |
14+
|---------|------|------|
15+
| 表格/公式/代码 | 实时链路已存裁剪图,但仅作精修中间产物(`crop/` 命名空间,REQ-159) | 无持久化记录、无图库消费、无区域级配图基础 |
16+
| 流程图/思维导图/架构图/图表(Image/Unknown) | 完全无裁剪无持久化;OCR 线性文本必然失真;AI 语义重建(REQ-056/058)V1.0 才实装 | **中间缺"图像即产物"兜底**——纯本地铁律下唯一诚实路径是先保存图 |
17+
| 笔记配图 | 只有整帧 full 图(屏段落配图,REQ-160) | 无区域级图(本版不做笔记消费,表留 screen_id 锚点待下版) |
18+
19+
**核心洞察**: 语义重建(V1.0 AI 补缝)之前,"保存图像本身"是本地优先架构下对非线性结构的正确降级——图比线性文本诚实。
20+
21+
## 二、头脑风暴裁决(2026-08-20)
22+
23+
| 议题 | 裁决 |
24+
|------|------|
25+
| 范围 | **两者都要**:结构三类(表格/公式/代码)+ 视觉型图结构(Image 区域)统一获得图像持久化能力 |
26+
| 触发方式 | **混合**:自动覆盖高频(结构三类 + Image 区域过过滤);手动框选补充低频/漏检 |
27+
| 消费场景 | **仅会话内图库**(浏览/删除);笔记内联消费留待下版 |
28+
| 手动框选表面 | **屏卡全帧图上框选**(复用屏卡流与 full 图;不碰实时链路) |
29+
| 自动范围 | **结构三类 + Image 区域**(Image 需 `diagram_likeness` 过滤防照片/装饰误收) |
30+
| 实现方案 | **方案 A+**:批量时机 + 屏内多帧选优(详见 §三) |
31+
32+
## 三、方案对比与性能结论
33+
34+
| 方案 | 内容 | 权衡 |
35+
|------|------|------|
36+
| A:纯批量 | 停止后对屏卡代表帧(first_seen)重跑版面分析 → 裁剪入库 | 架构最简;质量上限=屏卡帧 |
37+
| **A+(裁决)** | A + 裁剪源换成**屏时间窗内多归档帧中清晰度最高帧**(pick_sharpest 纯函数) | A 的复杂度拿 B 的大部分质量 |
38+
| B:在线采集状态机 | 实时链路挂 StructureTracker:区域跟踪 + 逐帧清晰度评估 → 最优帧裁剪 | 增量 CPU 小(区域匹配微秒级、清晰度评估复用边缘网格、编码每区域仅一次),但**状态机复杂度与实时链路回归风险大**(与 ScreenTracker/region_tracker 并存;v0.7.5 刚根治停止残留类问题);且屏卡代表帧已有 novelty 门控(动效中间帧本就不会成为屏卡帧),B 的质量优势被削弱 |
39+
40+
**性能结论(用户提问)**: B 的增量 CPU 负载很小(对比 OCR 数百 ms/次且已被变化检测+冷却门控,B 每帧增量几十微秒),真正的成本是状态机复杂度与实时链路回归风险 → 不选 B。
41+
42+
## 四、设计规格
43+
44+
### 4.1 数据层
45+
46+
**新表 `session_structure_images`**(`ensure_table` 幂等迁移,ADR-014 先例):
47+
48+
| 列 | 说明 |
49+
|----|------|
50+
| `id` | 主键 |
51+
| `session_id` | 会话(查询主路径,建索引) |
52+
| `screen_id` | 所属屏(NULL=旧数据无屏)——为将来笔记按屏消费留锚点 |
53+
| `kind` | `table` / `formula` / `code` / `image` / `manual`(字符串枚举,**不动** `RegionKind`——版面分析模块零改动) |
54+
| `bbox` | JSON `{x,y,w,h}` 帧坐标 |
55+
| `source_ts_ms` | 裁剪源帧时间戳 |
56+
| `crop_path` | `struct/{ts}.webp` 相对路径 |
57+
| `source` | `auto` / `manual` |
58+
| `created_at` | 入库时间 |
59+
60+
**存储**:`image_store` 新增 `struct/` 命名空间——与 `crop/`(精修中间产物)**语义分离**:`struct/` = 持久化结构图(图库消费),`crop/` = refine 候选。缩略图同步生成(复用现有缩略管线)。
61+
62+
**预算**:独立桶 `STRUCT_BUDGET_AUTO`(常量 80/会话,仅限自动捕获);**手动框选不设限**(用户主动行为不被预算驱逐)。auto 耗尽即停止本会话后续自动捕获(手动不受影响)。
63+
64+
**去重**:复用 `same_image` 双指纹(aHash+dHash,REQ-067 先例)——同屏同区域多帧候选只存一张;批量重跑幂等。
65+
66+
### 4.2 自动捕获(批量任务)
67+
68+
**触发**:会话停止后自动跑(与 REQ-159 结构精修同节奏);图库提供"重新捕获"按钮可重跑(去重保证幂等)。
69+
70+
**管线**(新模块 `structure_capture.rs`,纯函数核心 + 命令胶水,单文件 ≤300 行):
71+
72+
```
73+
capture_session_structures(session_id):
74+
屏列表(screens 派生查询,屏卡体系产出)
75+
每屏:
76+
① 帧候选:full/ 目录中时间戳 ∈ [first_seen, last_seen] 的归档帧
77+
(每屏采样上限 8 帧,超出均匀抽样——bound 解码成本)
78+
② pick_sharpest(candidates) → 最清晰帧(边缘能量评分,灰度网格复用 frame_features)
79+
③ grid_from_bgra(复用)→ analyze_layout(复用)
80+
④ 区域过滤:
81+
- table/formula/code → 直接候选(is_structural)
82+
- image → diagram_likeness(region_grid) ≥ 阈值 → 候选
83+
- text / unknown → 跳过(text 走 OCR 线性文本;unknown 归 V1.0 AI 补缝)
84+
⑤ 白边裁剪(image_crop 复用)→ WebP → struct/ + thumb/
85+
⑥ same_image 去重 → 预算检查 → 入库
86+
```
87+
88+
**`diagram_likeness(region_grid) -> f32`**(新纯函数,阈值 0.5 起步真机调参):
89+
- 边缘密度:框线/箭头结构多(复用边缘网格概念,frame_features 产出)
90+
- 面积占比:区域面积 / 屏面积 ≥ 阈值(照片贴图与结构图粗分)
91+
- 灰度方差:非纯色(防纯色装饰块误收)
92+
- 三特征加权综合;合成网格单测(流程图样/照片样/纯色样/阈值边界)
93+
94+
### 4.3 手动捕获(屏卡框选)
95+
96+
**交互**:原料屏卡 full 图 → 「框选截取」按钮进入选择模式(`BoxSelectOverlay` 拖框)→ 松开出**确认浮层**(裁剪预览 + 保存/取消,防误触产生垃圾图)→ 保存。
97+
98+
**命令**:`capture_structure_manual(session_id, screen_id, x, y, w, h)`(归一化 0-1 坐标):
99+
1. 解析屏卡 `image_ref` full 图;缺失 → 明确错误(前端禁用按钮并提示"该屏无图像")
100+
2. 归一化 → 像素坐标;越界自动钳制;<32×32px 拒绝
101+
3. **按用户框选原样裁剪**(不做白边裁剪——用户意图优先)→ `struct/` + 缩略图
102+
4. 入库:`kind=manual`,`source=manual`,`source_ts_ms=屏 first_seen`,bbox=裁剪框
103+
5. 不设预算上限
104+
105+
### 4.4 会话内图库 UI
106+
107+
**`ImageGallery.tsx` 扩展**(现 105 行,新增独立组件保持单文件 ≤300 行):
108+
- 新组件 `StructureImageSection.tsx`:结构图网格——kind 徽标(表格/公式/代码/图结构/手动)+ source 徽标(自动/手动)+ 时间 `MM:SS` + 屏号 + 删除按钮 + 「重新捕获」按钮 + 空态提示
109+
- 命令:`list_session_structure_images(session_id)` / `delete_structure_image(id)`(删记录+删文件——文件仅被本表引用,可安全删)/ `capture_session_structures(session_id)`(重跑)
110+
- 大图预览与参考图共用(见 4.6)
111+
112+
### 4.5 修复①:会话列表没有全选框
113+
114+
**现状**:`SessionListPanel` 有逐项勾选 + 批量操作栏(已选 N/批量转/批量删除/取消),无全选。
115+
**设计**:批量操作栏最左加「全选」复选框,**口径 = 当前筛选视图(filtered 集合)**:
116+
- 三态:全部选中(checked)/ 部分选中(indeterminate)/ 未选中
117+
- 点击选中 → `selected` = 当前 filtered 全部 id;再点 → 清空
118+
- 列表视图与课程分组视图共用(filtered 口径一致)
119+
- 段搜索命中视图批量栏隐藏(现状)→ 全选框自然不出现
120+
- 纯前端本地状态(selected 已是本地 Set),**零后端改动**
121+
122+
### 4.6 修复②:参考图片无法查看详情
123+
124+
**现状**:`ImageGallery` 缩略图无任何点击处理,无法查看大图。
125+
**设计**:新组件 `ImagePreviewOverlay.tsx`:
126+
- 点击缩略图 → 遮罩 + 大图(`contain` 适配窗口)
127+
- 信息栏:相对路径 + 时间戳 + 删除按钮
128+
- ESC / 点击遮罩关闭
129+
- 参考图集与结构图区段共用(一处实现两处消费)
130+
131+
### 4.7 降级链(本地优先铁律)
132+
133+
1. 新会话(screen_id + full 图 + 版面信息)→ 全能力自动捕获
134+
2. 旧会话无 screen_id → 屏列表空 → 自动捕获跳过(图库空态);手动框选需屏卡有图(无图禁用+提示)
135+
3. 无 full 归档帧(图集未开)→ 该屏自动跳过(不阻断其他屏)
136+
4. 版面分析空/失败 → 该屏跳过
137+
5. 全部失败 → 图库空态 + 手动框选仍可用(手动不依赖版面分析)
138+
139+
### 4.8 测试(AAA,纯函数优先)
140+
141+
- `diagram_likeness`:流程图样/照片样/纯色样/阈值边界(合成网格,layout_analyzer_tests 先例)
142+
- `pick_sharpest`:多帧选最大/空列表/全零
143+
- 批量管线:mock 屏+帧 → 候选集/去重/预算耗尽停止/幂等重跑
144+
- 手动命令:越界钳制/最小尺寸拒绝/无 image_ref 错误
145+
- DB:ensure_table 幂等/CRUD/旧库兼容
146+
- 前端:框选归一化坐标纯函数 + 真机手动清单(Vitest 基建维持 v0.8.0 裁决)
147+
148+
## 五、验收标准
149+
150+
- [ ] 重跑真实会话:停止后自动捕获表格/公式/代码入图库;PPT 流程图被捕获;照片/装饰**不**误收(阈值调参)
151+
- [ ] 图库:结构图区段徽标/时间/来源/删除生效;「重新捕获」幂等
152+
- [ ] 手动:屏卡框选 → 预览确认 → 入库;无图屏按钮禁用+提示
153+
- [ ] 修复①:全选框三态正确(当前筛选视图口径),批量转/批量删不受影响
154+
- [ ] 修复②:参考图/结构图点击均大图预览,信息栏/删除/ESC 关闭正确
155+
- [ ] 旧会话零回归;`cargo test` + `cargo clippy` 全绿;前端构建通过
156+
157+
## 六、需求登记(REQ-182~187,详见需求池)
158+
159+
| REQ | 内容 | 优先级 |
160+
|-----|------|--------|
161+
| REQ-182 | 结构图自动捕获:批量任务(停止后触发+图库可重跑)——屏内选优帧 → 版面分析 → table/formula/code 直收 + Image 过 diagram_likeness → 白边裁剪入库 | P1 |
162+
| REQ-183 | 结构图持久化:session_structure_images 新表 + struct/ 命名空间与缩略图 + 独立预算(auto 80/会话,manual 不限)+ same_image 去重 | P1 |
163+
| REQ-184 | 手动结构图截取:屏卡全帧图框选(BoxSelectOverlay + 确认浮层)→ capture_structure_manual(归一化/钳制/最小尺寸拒绝) | P1 |
164+
| REQ-185 | 会话内结构图库:ImageGallery 扩展 StructureImageSection(kind/source 徽标 + 时间 + 屏号 + 删除 + 重新捕获) | P1 |
165+
| REQ-186 | 修复:会话列表全选框(当前筛选视图口径 + indeterminate 三态) | P2 |
166+
| REQ-187 | 修复:参考图片详情查看(ImagePreviewOverlay 大图预览,参考图/结构图共用) | P2 |
167+
168+
## 七、明确不做(本版裁决)
169+
170+
- **笔记内联消费**(下版;表已留 screen_id 锚点,配图链路 REQ-160 已就绪)
171+
- **在线采集状态机**(方案 B——复杂度/回归风险大于收益)
172+
- **手动类型标注**(流程图/思维导图选择器——YAGNI)
173+
- **AI 语义重建**(V1.0,REQ-056/058 既规划;本版图像即最终产物)
174+
- **导出/右键另存**(图库可删除已够,导出随笔记消费下版评估)
175+
- **diagram_likeness 模型化**(规则版先行,模型版属 V1.0 版面模型组范畴)

‎docs/product/requirements-pool.md‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,21 @@
252252
| REQ-180 | 结构元数据:StructureStats 并入 purify_stats + RULE_VERSION 递增 note-rules-0.7.6 | P2 | 已实施(2026-08-20) | v0.7.6 | REQ-171 机制延续;FilterStats 三新字段 serde(default);旧笔记 NULL 诚实降级 |
253253
| REQ-181 | 黄金语料回归扩展:会话31 夹具 → 期望带结构笔记断言(TDD) | P1 | 已实施(2026-08-20) | v0.7.6 | REQ-172 机制扩展(2 例:章节标题+词汇表);预览/落库双出口同函数同口径 |
254254

255+
### v0.7.7 · 非线性结构图像捕获与持久化(结构图)+ 会话管理两处修复(2026-08-20 头脑风暴裁决)
256+
257+
> 版面分析已能分类 text/table/formula/code/image/unknown,但非线性文本结构缺"图像级持久化"闭环:表格/公式/代码裁剪图仅作精修中间产物;流程图/思维导图等(Image/Unknown)完全无裁剪无持久化;AI 语义重建(REQ-056/058)V1.0 才实装——本版用"图像即产物"兜底(ADR-010 诚实降级)。
258+
> 设计规格 [头脑风暴 结构图 v0.7.7([ ] 已归档)](../archive/2026-08-20/brainstorming-structure-images-v0.7.7.md) · [v0.7.7 版本文档](../versions/v0.7.7.md)。
259+
> 裁决:方案 A+(批量时机+屏内多帧选优,不做在线状态机——增量 CPU 小但状态机复杂度/实时链路回归风险大);混合触发(自动=结构三类+Image 过 diagram_likeness,手动=屏卡框选);消费=会话内图库(笔记内联下版);并修两处会话管理体验问题。
260+
261+
| ID | 需求 | 优先级 | 状态 | 目标版本 | 备注 |
262+
|----|------|--------|------|---------|------|
263+
| REQ-182 | 结构图自动捕获:批量任务(停止后触发+图库可重跑)——屏内多帧选优(pick_sharpest 边缘能量)→ 版面分析复用 → table/formula/code 直收 + Image 过 diagram_likeness(边缘密度+面积占比+灰度方差加权)→ 白边裁剪入库 | P1 | 已排期 | v0.7.7 | 每屏采样 ≤8 帧 bound 解码成本;text/unknown 跳过(unknown 归 V1.0 AI 补缝);重跑幂等(same_image 去重) |
264+
| REQ-183 | 结构图持久化:session_structure_images 新表(kind/bbox/screen_id/source_ts/source)+ struct/ 命名空间(与 crop/ 精修中间产物语义分离)+ 缩略图 + 独立预算(auto 80/会话常量,manual 不限)+ same_image 去重 | P1 | 已排期 | v0.7.7 | ensure_table 幂等迁移;RegionKind 不动(kind 字符串枚举);screen_id 留笔记消费锚点 |
265+
| REQ-184 | 手动结构图截取:屏卡全帧图框选(BoxSelectOverlay 拖框 + 确认浮层防误触)→ capture_structure_manual(归一化坐标/越界钳制/<32×32 拒绝/原样裁剪不白边) | P1 | 已排期 | v0.7.7 | 无 image_ref 屏禁用+提示;手动不设预算上限(用户主动行为) |
266+
| REQ-185 | 会话内结构图库:ImageGallery 扩展 StructureImageSection(kind/source 徽标+时间+屏号+删除+重新捕获按钮+空态) | P1 | 已排期 | v0.7.7 | list_session_structure_images / delete_structure_image / capture_session_structures 三命令 |
267+
| REQ-186 | 修复:会话列表全选框(当前筛选视图 filtered 口径 + indeterminate 三态;列表/分组视图共用;纯前端本地状态零后端改动) | P2 | 已排期 | v0.7.7 | 段搜索命中视图批量栏隐藏→全选框自然不出现 |
268+
| REQ-187 | 修复:参考图片详情查看(ImagePreviewOverlay 大图预览遮罩 + 相对路径/时间信息栏 + 删除 + ESC/点遮罩关闭;参考图/结构图共用) | P2 | 已排期 | v0.7.7 | 修复 ImageGallery 缩略图无点击处理现状 |
269+
255270
### V1.0 · 体验增强(远期)
256271

257272
| ID | 需求 | 优先级 | 状态 | 目标版本 | 备注 |

0 commit comments

Comments
 (0)