图片转 Visio 矢量重绘
把一张位图里的架构图,按内容重新画成原生可编辑的 Visio 矢量形状。
触发条件
用户给出一张图(PNG/JPG/截图/照片)并表达以下任一意图:
- "把这张图做成 vsdx / 画成 Visio"
- "按图片内容重画一份可编辑的"
- "不要将图片直接插入 Visio"(明确要求不贴图)
- "这张架构图矢量化"
核心原则
| 要求 | 说明 |
|---|---|
| 不贴图 | 绝不 Page.Import 或插入图片对象。原图只作为"内容来源",不出现在产物里 |
| 逐元素重画 | 每个框、每条线都是独立 Visio 形状,可选中、可拖动、可改字 |
| 结构一致 | 位置关系、层次、配色语义要还原原图 |
| 允许纠错 | 原图若有标注错误(如标签重复、分类不合理),按逻辑修正并在回复中告知用户 |
工作流(6 步)
① 读图 → ② 拆解结构 → ③ 写数据脚本 → ④ 生成 vsdx → ⑤ 导出 PNG → ⑥ 对比修正
Read 方法论 模板改造 build.ps1 export.ps1 与原图逐区核对
↑ │
└────── 迭代 ───────┘
① 读图
用 Read 工具直接读图片文件(多模态能力)。读的时候就要开始拆解,不要读完后凭印象画。
② 拆解结构(核心,见 references/01-看图拆解方法论.md)
产出三样东西:
- 区域清单:顶部/主体/侧栏/底部各是什么
- 配色语义表:每种颜色代表什么角色
- 层级树:哪块包含哪块
③ 写数据脚本
复制 scripts/template_gen_data.py,改内容。不要从零写——模板已含全部 helper。
④ 生成 vsdx
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass -Force
& "scripts\build_visio.ps1" -JsonPath "_visio_data.json" -OutPath "输出图.vsdx"
⑤ 导出 PNG
& "scripts\export_png.ps1" -VsdxPath "输出图.vsdx" -OutDir "预览"
⑥ 对比修正(不可省略)
读导出的 PNG,与原图逐区域对比。这一步能抓出:
| 常见问题 | 表现 | 修正 |
|---|---|---|
| 文字溢出 | 字超出框 | 增大 h 或减小 fs |
| 元素重叠 | 两块叠在一起 | 检查 Y 累加 |
| 方向错 | 该竖排的横排了 | 检查循环写的是 x 还是 y |
| 层级丢失 | 看不出包含关系 | 加底色块作背景,子卡片叠在上面 |
| 颜色不对应 | 视觉层次变了 | 核对配色语义表 |
布局还原要点
坐标系
- 页面 A2 横向:
PW, PH = 23.4, 16.5(英寸) - 页边距
0.4 - Y 从上往下累加(脚本内部会自动翻转成 Visio 的左下原点坐标)
- 单位统一用英寸,文字大小用
pt(由fs参数控制)
高度估算公式
标题条高 ≈ 0.40 ~ 0.60
内容行高(单行)≈ 0.23 ~ 0.28
卡片总高 = 标题高 + 行数 × 行高 + 上下 padding(各 0.10~0.14)
宁可预留略高,也不要让文字挤出去——溢出比留白难看得多。
分区顺序
1. 先切竖向大块(左栏 / 主体 / 右栏)
2. 再在主体内切横向行(云 / 网 / 端…)
3. 行内切列(等宽均分)
4. 列内切卡片(标题条 + 内容)
5. 最后放页眉、页脚、角标
层级表达
靠三件事表达"包含":
- 大底色块先画(作为容器背景)
- 子卡片后画,叠在容器内(留 0.08~0.15 内边距)
- 容器边框用深一档的颜色,
lw加粗(1.0~1.2)
配色语义提取
架构图里颜色 = 角色。动手前先列一张表:
深蓝 NAVY (31,78,121) → 主标题 / 层名 / 页眉
亮蓝 BLUE (46,117,182) → 卡片标题条
浅蓝 XLBLUE(222,235,247) → 容器背景
白 WHITE → 内容区
橙 / 绿 / 紫 / 黄 → 区分不同归属方(同色 = 同类)
同色必定同角色,这是还原视觉层次的关键。如果原图用了某个色只出现一次,多半是强调,单独记下来。
处理原图的"不完整"和"错误"
架构图常见两种情况,都要主动处理:
① 省略号 / "…" / "等" 按其归类补全完整列表,并在页脚注明"原图中『…』表示未完整列出的同类项目,已按其归类完整列出"。
② 标注错误 例如某分类里同一个标签出现两次(疑似原图标注失误)。按合理逻辑重新拆分,并在回复中明确告诉用户:
原图右半"信息物理基础设施"里"低空通信基础设施"重复出现两次,疑似标注错误,我按逻辑拆成了 5 段:通信 → 导航 → 监视 → 其他保障 → 管控。如需保留原样请告诉我。
模板脚本用法
scripts/template_gen_data.py 已含全部 helper:
| helper | 用途 |
|---|---|
newpage(name) |
建页 |
add(...) |
基础矩形(最常用) |
card(...) |
标题条 + 内容框 |
section(...) |
带标题条的分区块(用于端层这类多段) |
sidebar(...) |
左右竖栏(标题 + 若干项) |
cols(n, gap) |
n 列等宽的 x 坐标 |
footer(...) |
页脚说明 |
改造流程:
- 复制模板 → 重命名
- 改
PAGES里的内容 - 运行输出 JSON
- 跑
build_visio.ps1
完整示例:低空智能网联体系参考架构
原图是一张网传的架构截图,要求重绘为 vsdx。
| 项目 | 结果 |
|---|---|
| 产出 | 1 页 A2 横向,91 个原生矢量形状 |
| 结构 | 顶部 4 场景 + 左标准栏 + 右安全栏 + 云/网/端三层 + 底部 5 参与方 |
| 迭代 | 2 轮(首轮布局可用,微调后定稿) |
| 纠错 | 原图"低空通信基础设施"标签重复,按逻辑拆为 5 段 |
布局骨架(可直接复用):
PW, PH = 23.4, 16.5
LX, LW = 0.4, 2.5 # 左竖栏
RX, RW = 20.5, 2.5 # 右竖栏
CX = LX + LW + 0.2 # 主体起点
CW = RX - CX - 0.2 # 主体宽度
ROW_H = [3.0, 2.4, 剩余] # 云 / 网 / 端 三行高度
常见问题
Q:能不能直接把图片插入 Visio 然后描图? A:技术上可以,但违反用户"不要贴图"的要求,产物也不可编辑。始终用矢量形状重画。
Q:原图很复杂,形状超过 200 个怎么办? A:优先保证结构和主要元素完整。细碎的装饰(阴影、渐变、图标)可以省略——架构图的信息价值在结构和文字,不在装饰。
Q:用户要多页怎么办?
A:同一份 JSON 里放多个 newpage(),每页独立布局。参考 visio-com-automation skill 的 9 页案例。
Q:中文字体显示不对?
A:build_visio.ps1 已处理(用字体 ID 而非名称,YaHei ID=174)。详见下方踩坑清单。
踩坑清单(绘制引擎层)
已内置在 build_visio.ps1 里,此处列出备查:
- 字体用数字 ID:
Char.Font = $doc.Fonts.Item("Microsoft YaHei").ID(不是字体名) - 箭头是
EndArrow/BeginArrow,不是LineEndArrow - Y 轴翻转:
$y = $pageH - $top - $h - 不要删最后一页:复用
Pages.Item(1)作首页 - PS 5.1 中文编码:脚本保持纯 ASCII,中文走 UTF-8 JSON
- 加粗:
Char.Style = "1" - 进程残留:
finally里Quit()+ReleaseComObject+GC - exit code 会骗人:用日志文件捕获输出再读
- 生成失败后先查残留 Visio 进程:构建在 SaveAs 处失败(日志停在
page done、无 SAVED)时, 常有卡死的 VISIO 进程占着文件 →Get-Process VISIO | Stop-Process -Force,删旧文件再重跑; 每轮生成结束后主动清一次 Visio 进程更稳妥 - conn 的 dash 是 LinePattern 编号:0=线不显示(箭头也消失),实线必须 1,虚线 2
- 椭圆:
add(..., oval=True)(引擎 DrawOval);云朵等不规则形用大椭圆近似,页脚注明
依赖
- 本机需安装 Microsoft Visio(Office16,COM
Visio.Application已注册) - Python 3(生成 JSON,标准库即可)
- Windows PowerShell 5.1+
本 skill 与
visio-com-automation共享同一套绘制引擎,后者涵盖更多通用场景(多页架构图、接口表、标准矩阵)。当前 skill 专注「图片 → 矢量」这一特定入口。