图片转 VSDX(image-to-vsdx)
用途
将用户提供的一张图(流程图、结构图、架构图、思维导图、网络拓扑图、白板照片等)转换为可编辑的 Microsoft Visio VSDX 文件:图中的框重建为可编辑形状、箭头重建为连接线、文字重建为可编辑文本,而不是把原图嵌成一张不可编辑的位图。
何时使用
- 用户上传或提供一张图片(PNG/JPG/WebP,≤20MB),并要求"转 VSDX""转 Visio""转成 Visio 可编辑格式"
- 图中包含清晰的框、连线、文字(流程图/结构图类),而不是纯照片或纯艺术图
- 用户需要拿到一个可在 Microsoft Visio / WPS 里继续编辑的 .vsdx 文件
三条转换路径(运行时按顺序自动选择)
按下列顺序检查,命中第一条可用的路径即执行:
路径 A:LayerBack 云端 API(首选,质量最高)
- 前置条件:环境变量
LAYERBACK_API_KEY已设置 - 执行方式:若已安装
layerback-image-to-vsdxskill,按其工作流调用 LayerBack 官方 API;否则直接调用 LayerBack API(POST https://layerback.com/api/v1/convert,请求头x-api-key,随后轮询 job 状态并下载 vsdx) - 优点:框、线、文字全自动重建,一次转换同时返回 VSDX/PPTX/drawio/SVG
- 成本:1 次 10 积分;上传到云端,72 小时内删除
- 注意:转换前向用户确认"源文件、大小、上传目的地、积分消耗";不得在对话/日志/文件中暴露 API key
路径 B:draw.io 桌面版(本地 GUI,不花积分)
- 前置条件:路径 A 不可用,且用户本机已安装 draw.io 桌面版
- 执行方式:若已安装
drawio-to-visioskill,按其工作流执行(先把图在 draw.io 中重建为 .drawio XML,再导出 VSDX);否则指导用户:draw.io 打开 → 照图用形状库重建 → File → Export as → Visio(VSDX) - 优点:完全本地、不花积分;缺点:需要用户在 GUI 里操作重建
路径 C:本地 Python 拼装(沙箱内可完成,兜底)
- 前置条件:路径 A、B 都不可用
- 执行方式:AI 看懂图后手写
scene.json,或 OCR + OpenCV 框检测自动提取"矩形框坐标、框内文字、连线起终点",再调用scripts/build_vsdx.py拼装 VSDX - 优点:完全本地、沙箱内即可完成;缺点:OCR 对中文、密排文字的识别率不一定 100%,连线关系容易识别错,需人工校对
- 依赖:
build_vsdx.py只用 Python 标准库(零第三方依赖);OCR 兜底另需 pytesseract + OpenCV(见references/setup-guide.md)
工作流
- 确认输入图片格式(PNG/JPG/WebP)和大小(≤20MB)
- 检查
LAYERBACK_API_KEY(运行echo $LAYERBACK_API_KEY或echo %LAYERBACK_API_KEY%)
- 已设置 → 路径 A
- 未设置 → 检查 draw.io 桌面版是否可用(问用户或检测常见安装路径)- 可用 → 路径 B
- 不可用 → 路径 C
- 执行所选路径
- 验证输出 VSDX(见下节)
- 报告输出绝对路径 + 验证结果 + 转换局限(如有)
验证输出 VSDX
生成后必须解压校验(用 Python zipfile,不调用任何会结束进程的 COM/WPS 接口):
- 是 ZIP/OPC 包,不是把 PDF/图片重命名成 .vsdx
[Content_Types].xml含application/vnd.ms-visio.drawing.main+xmlvisio/pages/page1.xml存在且含至少一个<Shape>节点- 框的文字落在
<Shape>的<Text>节点中,而非嵌成图片
路径 C 的详细做法
核心原则:AI 视觉理解 + 手写 scene.json 是主路径,OCR 自动识别是兜底。
主路径:AI 看懂图后手写 scene.json(推荐)
AI 看到流程图/结构图后,直接在脑子里构建节点和连线,按下面的约定手写 scene.json(就像手写 SVG XML 一样),然后跑随包脚本 build_vsdx.py 生成 VSDX:
python scripts/build_vsdx.py scene.json output.vsdx
build_vsdx.py 三版都随包提供(它是 VSDX OPC 字节级拼装脚本,模型现场写不出来),只用 Python 标准库,零第三方依赖。
手写约定(节点/连线坐标都是图片像素,原点左上角):
- 节点的
x/y= 中心点像素坐标,w/h= 宽高像素 - 连线的
from_port/to_port= 端口方向(top/bottom/left/right/center) - 容器 = 大圆角矩形(自带顶部标题),节点加
container字段引用容器 id - 形状
shape:rect/rounded/ellipse/diamond(默认rect) - 字体
font:family(默认 SimSun)、size_pt(字号磅)、bold
build_vsdx.py 内部做:像素→英寸缩放(1/96)+ Y 轴翻转(页面高 - y_px)+ 拼 OPC VSDX。
兜底:AI 看不懂图时用 OCR + 框检测
AI 看到图无法直接理解结构(太模糊、太复杂、或者只是"图片转 Visio"需求而非结构化流程图)时,用 pytesseract OCR + OpenCV 框检测自动提取"框坐标 + 框内文字 + 连线起终点",输出同样格式的 scene.json,再交给 build_vsdx.py。但简单流程图的自动识别效果差(框检测漏检、文字靠 OCR),所以优先用主路径。
- 脚本正式版 / 脚本离线版:直接调用随包脚本
python scripts/image_to_scene.py input.png scene.json [--lang chi_sim+eng] - 纯提示词版:该 OCR 脚本不随包提供,模型按本 SKILL.md 现场写(pytesseract OCR + OpenCV 框检测,输出 scene.json),写法见「纯提示词版如何单独使用」
python scripts/build_vsdx.py scene.json output.vsdx
scene.json 协议
{
"page": {"width": 380, "height": 403},
"nodes": [
{"id": "n1", "text": "文字", "x": 190, "y": 120, "w": 120, "h": 40,
"shape": "rounded", "font": {"family": "SimSun", "size_pt": 12, "bold": false},
"fill": "#f2f2f2", "line": "#000000", "container": "c1"}
],
"containers": [
{"id": "c1", "text": "容器标题", "x": 190, "y": 200, "w": 300, "h": 200}
],
"edges": [
{"id": "e1", "from": "n1", "from_port": "bottom", "to": "n2", "to_port": "top",
"end_arrow": true, "label": "连线文字"}
]
}
字段说明:
page:原图片像素尺寸(width/height),用于 Y 轴翻转和页面尺寸nodes[].shape:rect/rounded/ellipse/diamond(默认 rect)nodes[].font:family(字体名,默认 SimSun)、size_pt(字号磅)、bold(粗体)nodes[].fill/line:填充色 / 边框色(十六进制)nodes[].container:所属容器 idcontainers:分组容器(大圆角矩形 + 顶部标题),画在节点下层edges[].from/to:节点 id;from_port/to_port:端口方向top/bottom/left/right/center(默认 center),连线从节点边缘对应端口进出edges[].end_arrow:终点是否带箭头(默认 true)
依赖
- 路径 A:
layerback-image-to-vsdxskill(或 LayerBack API)+LAYERBACK_API_KEY - 路径 B:
drawio-to-visioskill + draw.io 桌面版 - 路径 C:
scripts/build_vsdx.py(零依赖)+ 可选 pytesseract + OpenCV(仅 OCR 兜底)
依赖清单与安装见 skill-dependencies.json、references/setup-guide.md、scripts/check_environment.py。
约束
- 不得把图片上传到未经用户确认的第三方服务
- 不得暴露 API key
- 不承诺"像素级还原"——结构、文字、连线可编辑即可;布局/字体/箭头样式允许与截图有细微差异
- 若图片是纯照片/无框线结构,明确告知不适合转换,不要强行输出
打包命名规则
- skill 压缩包共 3 个,文件名带日期时间版本号(
v年月日时分): - 纯提示词版:
图片转VSDX_纯提示词版_v{日期时间}.zip - 脚本正式版:
图片转VSDX_脚本正式版_v{日期时间}.zip - 脚本离线版:
图片转VSDX_脚本离线版_v{日期时间}.zip - 三个版本差异:
- 纯提示词版 = SKILL.md + references + skill-dependencies.json +
build_vsdx.py+assets/template.vsdx+check_environment.py(含 VSDX 字节级拼装脚本与模板,OCR 兜底脚本由模型现场写) - 脚本正式版 = 纯提示词版 +
image_to_scene.py(OCR 兜底脚本),无本地 wheel,联网装 pytesseract/opencv - 脚本离线版 = 脚本正式版 + 本地 wheel(pytesseract/opencv-python/numpy)+
install_offline.py(装依赖不联网)
压缩包层级结构(适应官方)
- 三个压缩包内,顶层目录名统一为 frontmatter 的
name(本 skill 为image-to-vsdx),zip 内不得有其他顶层目录。 - 模板文件放 skill 目录内(本 skill 为
assets/template.vsdx),不放 zip 顶层(三版都有)。 - 离线依赖 wheel 放 skill 目录内(本 skill 为
dependencies/python/),不放 zip 顶层(仅脚本离线版)。 - zip 内路径统一用
/分隔,保留顶层 skill 目录。
打包操作规则(防破坏,其他 AI 打包时须遵守)
- 打包 = 从 skill 源目录复制到临时快照 → 在快照上校验 → 生成 zip,全程不修改、不删除 skill 源目录任何文件。
- 三个版本共用同一份 SKILL.md;差异只在
scripts/(纯提示词版无image_to_scene.py)、dependencies/(仅离线版)、install_offline.py(仅离线版)。 - 版本号(日期时间
v年月日时分)每次打包必须比上一次新;替换旧版本号 zip 前先备份。 - 不覆盖、不删除任何源文件;发现源文件缺失或格式不合规时先停下问用户,不擅自补写业务逻辑。
- 打包完成后必须跑
validate通过才交付。
纯提示词版的脚本策略(通用规则)
- "纯提示词版"不排斥脚本——凡是模型现场写不出来的字节级/底层操作、绝对必须的固定依赖,都该给就给。
- 本 skill 的判断:
build_vsdx.py+assets/template.vsdx是 VSDX OPC 字节级拼装(依赖 Visio XML 的 Shape/Cell/Geometry/Connect 精确结构 + 一个真实模板文件),模型现场写不出来 → 纯提示词版保留;check_environment.py是环境检查(基础设施)→ 保留;image_to_scene.py(pytesseract OCR + OpenCV 框检测)是常规图像处理,模型能现场写 → 纯提示词版不含,脚本版含。 - 判定原则:脚本是"模型现场写不出来"→ 含;脚本是"模型能现场实现"→ 不含
纯提示词版如何单独使用
纯提示词版不含 image_to_scene.py,主路径(AI 看懂图手写 scene.json → 调自带 build_vsdx.py)零第三方依赖、可直接用。仅当走 OCR 兜底时,模型按本 SKILL.md 现场写 OCR + 框检测 Python(pytesseract 读文字、OpenCV 找矩形框与连线,输出 scene.json),调自带 check_environment.py 检查环境 + 联网装 pytesseract/opencv。典型流程:AI 看懂图手写 scene.json → python scripts/build_vsdx.py scene.json output.vsdx → 验证 VSDX;看不懂图时再现场写 OCR 脚本兜底。