---
name: image-to-vsdx
description: 将流程图、结构图、架构图、思维导图等图片（PNG/JPG/WebP）转换为可编辑的 Microsoft Visio VSDX 文件。运行时按 LAYERBACK_API_KEY、draw.io 桌面版、本地 Python 三条路径自动选择，输出 VSDX 格式。触发词：图片转 VSDX、图片转 Visio、image to vsdx、流程图转 Visio、截图转 Visio。
version: 1.0.0
agent_created: true
---

# 图片转 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-vsdx` skill，按其工作流调用 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-visio` skill，按其工作流执行（先把图在 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`）

## 工作流

1. 确认输入图片格式（PNG/JPG/WebP）和大小（≤20MB）
2. 检查 `LAYERBACK_API_KEY`（运行 `echo $LAYERBACK_API_KEY` 或 `echo %LAYERBACK_API_KEY%`）
   - 已设置 → 路径 A
   - 未设置 → 检查 draw.io 桌面版是否可用（问用户或检测常见安装路径）
     - 可用 → 路径 B
     - 不可用 → 路径 C
3. 执行所选路径
4. 验证输出 VSDX（见下节）
5. 报告输出绝对路径 + 验证结果 + 转换局限（如有）

## 验证输出 VSDX

生成后必须解压校验（用 Python zipfile，不调用任何会结束进程的 COM/WPS 接口）：

- 是 ZIP/OPC 包，不是把 PDF/图片重命名成 .vsdx
- `[Content_Types].xml` 含 `application/vnd.ms-visio.drawing.main+xml`
- `visio/pages/page1.xml` 存在且含至少一个 `<Shape>` 节点
- 框的文字落在 `<Shape>` 的 `<Text>` 节点中，而非嵌成图片

## 路径 C 的详细做法

**核心原则：AI 视觉理解 + 手写 scene.json 是主路径，OCR 自动识别是兜底。**

### 主路径：AI 看懂图后手写 scene.json（推荐）

AI 看到流程图/结构图后，直接在脑子里构建节点和连线，按下面的约定手写 scene.json（就像手写 SVG XML 一样），然后跑随包脚本 `build_vsdx.py` 生成 VSDX：

```bash
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），写法见「纯提示词版如何单独使用」

```bash
python scripts/build_vsdx.py scene.json output.vsdx
```

### scene.json 协议

```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`：所属容器 id
- `containers`：分组容器（大圆角矩形 + 顶部标题），画在节点下层
- `edges[].from` / `to`：节点 id；`from_port` / `to_port`：端口方向 `top`/`bottom`/`left`/`right`/`center`（默认 center），连线从节点边缘对应端口进出
- `edges[].end_arrow`：终点是否带箭头（默认 true）

## 依赖

- 路径 A：`layerback-image-to-vsdx` skill（或 LayerBack API）+ `LAYERBACK_API_KEY`
- 路径 B：`drawio-to-visio` skill + 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 脚本兜底。
