AI 图像工作室 (image-gen-studio)
在对话中弹出交互式 HTML 图像工作台,本地代理转发AI 图像 API,完整支持五大能力:
| 能力 | Gemini 引擎(当前可用) | gpt-image-2 引擎 |
|---|---|---|
| 文生图 | /v1beta/...:generateContent |
/v1/images/generations |
| 文改图(单图+文字) | 单图 inline_data 多模态编辑 | /v1/images/edits + image |
| 遮罩编辑 | 红色高亮标注法(多模态理解) | /v1/images/edits + 原生 mask PNG |
| 多图融合(2-10 张) | 多 image parts 直传 | /v1/images/edits + image[] |
| 分辨率 | 跟随提示词/比例(~1K-2K) | 1K / 2K / 4K(16 倍数校验) |
| 资产库 + LLM 识别 | 生成结果自动保存 / gpt-5.6-luna→gemini 识别 | 同左 |
v2 新增(2026-08-21)
- 通讯诊断与自动修复:前端失败自动弹诊断面板(错误分类:502 上游断连 / 401 Key 无效 / 503 模型无通道 / 代理不可达 / 超时),逐项检测浏览器网络→本地代理→上游 API,一键「重试上次操作」。
- 生成结果本地资产库:每次生成/编辑/融合自动保存到
--assets-dir(默认$MICU_ASSETS_DIR或当前目录assets/),前端「🗂️ 我的资产」Tab 网格浏览、下载、删除;资产 API:POST /api/assets/save、GET /api/assets/list、GET /api/assets/file/<name>、DELETE /api/assets/<name>。 - LLM 图片识别:
POST /api/vision传{image_b64, mime, api_keys:{gemini,gpt}, engine},服务端按 gpt-5.6-luna(OpenAI 端点)→ gemini-3-pro-image-preview(原生端点)顺序自动回退,解析 9 维度:图片类型/风格/时代/元素/镜头角度/配色/搭配类型/穿搭类/视觉类,输出 JSON。
v3 新增(2026-08-21):自动分类归档 + GitHub 同步
完整自动链路:生成图片 → 保存资产 → 后台自动识别「图片类型」→ 写回 index.json 的 meta.category → 按分类建目录 → 上传 GitHub 仓库 sangjiexun/digital-asset → 重建 README.md 目录树。
- github_sync.py(
scripts/github_sync.py):用 GitHub Contents API(api.github.com,Python urllib,绕过 git push 代理 502)上传图片到{分类目录}/{文件名},重建 README.md(总览统计 + 树状目录 + 分类明细表)。支持--watch监听模式、--dry-run预演。 - 代理自动触发:
POST /api/assets/save带auto_enhance:true+meta_keys:{gemini,gpt}时,保存响应立即返回,后台线程「识别→写回 category→调 github_sync.py 同步」。 - 手动触发:
GET /api/assets/sync(前端「🚀 同步到 GitHub」按钮)。 - 前端资产卡:显示分类徽标(识别中/分类名),顶部 GitHub 仓库链接。
- 分类规则:
meta.category或meta.图片类型→ 非法字符转_,无分类归unsorted/。
关键坑点(必记):
- GitHub Contents API 的 中文路径必须先
urllib.parse.quote(path, safe="/"),否则 urllib 请求行触发UnicodeEncodeError: ordinal not in range(128)。 - GitHub PAT 从 Keychain 读:
security find-internet-password -s github.com -w(40 位),脚本内get_token()已封装,不硬编码。 api.github.com用 Python urllib 可直连(网页 github.com 被代理拦、git push 502,但 API 正常)。- README 相对链接中文路径
./数字艺术/xxx.jpg在 GitHub 网页端可正常跳转。
v4 新增(2026-08-21):手动上传照片到指定分类
- 前端:资产 Tab 顶部新增「📤 上传照片到数字资产分类」卡片——拖拽/点击多选图片(≤10 张)→ 下拉选择分类(或自定义分类名)→ 可选自定义文件名 → 上传。
- 后端:
GET /api/assets/categories返回分类列表(本地 index 已有分类 + github_sync 扫描 + 常见分类兜底)。POST /api/assets/uploadbody{data_b64, ext, category, name?}保存到本地资产(写死meta.category)+ 后台同步 GitHub。- 自定义文件名自动清洗非法字符、扩展名校验(png/jpg/jpeg/webp/gif/bmp)、重名自动加序号去重。
- 上传后自动同步到 GitHub
{分类}/{文件名},支持中文文件名。
v4.1 修复(2026-08-21):上传预览图 + 每次同步 README
Bug 1:资产网格里中文文件名图片显示黑色占位
- 根因:
do_GET路由assets_get(name)拿到的name是 URL 编码形式(如%E4%B8%AD...jpg),未unquote就传给os.path.basename,导致os.path.isfile找不到真实中文文件 → HTTP 404 → 前端<img src>加载失败。 - 修复:
do_GET/do_DELETE路由处对name调urllib.parse.unquote(path[...])解码。
- 根因:
Bug 2:每次上传没触发 README 更新
- 根因:旧
_trigger_github_sync调sync_once全量扫描本地资产,遇到沙盒 SIGKILL (exit 137) 就提前终止,README 没机会重建。 - 修复:拆为「单文件快速通道 + 独立 README 重建」两个子命令
github_sync.py --upload-only NAME --upload-category CAT --upload-stdin:只同步一张图(从 stdin 读字节避免落盘)。github_sync.py --rebuild-readme:单独重建 README。proxy_server._trigger_github_sync(name, category, img_bytes)接收三参数,在assets_upload末尾串行跑两个独立 subprocess(即使第一段挂掉 README 也会重建)。
- 关键坑:
bytesinput 不能配text=True(会触发'bytes' object has no attribute 'encode'),要用capture_output=True(无 text)+.decode('utf-8','replace')。
- 根因:旧
前端
renderUploadPreview改造:DOM API 替代 innerHTML 拼接;FileReader.readAsDataURL替代URL.createObjectURL(更稳,避 iframe 沙盒限制 + 内存泄漏);加文件名 label(>10 字截断 + hover 显示全名);删除按钮改 addEventListener + stopPropagation。
⚠️ 502 根因与修复(2026-08-21 实测确认)
- 根因:Python urllib 的 TLS/HTTP 指纹被上游 Cloudflare 拦截。带图的大 JSON 请求(编辑/多图融合 base64)直接
SSL: UNEXPECTED_EOF_WHILE_READING/Remote end closed connection,而同请求用系统 curl 100% 成功。 - 修复:proxy_server.py 改用系统 curl 子进程转发上游请求 + 强制浏览器 UA(curl 转发时忽略传入 UA,一律
-H "User-Agent: Mozilla/5.0 ... Chrome/126.0"),502/524/空响应自动指数退避重试最多 3 次。 - 识别引擎 gpt-5.6-luna 状态:2026-08-21 实测 Gemini Key 分组下
model_not_found(503,无可用 channel,属 vip_2_image 分组);工作台已做自动回退,等用户换新 Key 后 gpt-5.6-luna 即可用。
标准启动流程(用户要交互式生图时)
# 1. 后台启动代理服务器(端口 8230,被占用时换 --port 8231 等)
python3 ~/.workbuddy/skills/image-gen-studio/scripts/proxy_server.py \
--port 8230 --assets-dir "$HOME/image-gen-studio-assets"
# 2. 用 present_files 展示 http://localhost:8230 打开工作台
# (HTML 文件本体在 ~/.workbuddy/skills/image-gen-studio/assets/image-studio.html)
重要:
- 代理必须在沙盒外运行(需要绑定端口 + 出网),Bash 启动时若沙盒拦截需申请权限
- 启动后先自己 curl 一次
http://localhost:8230/api/health(返回{"ok":true,"version":"2.0"})验证代理;再 curlhttp://localhost:8230/api/v1/models(带 Gemini Key Bearer 头)验证上游 - 工作台默认引擎 = Gemini(Key 有效);gpt-image-2 的 vip_2_image Key 若 401,提示用户去 https://www.micuapi.ai 令牌页面换新 Key,填入工作台「设置」页
- 代理进程是长驻服务,会话结束不必杀掉;端口冲突时换端口重启
快速直出模式(用户只说"生成一张 XX")
不必开工作台,直接 curl 生图并 present_files:
# Gemini 文生图(可用线路)
curl -s -X POST "https://www.micuapi.ai/v1beta/models/gemini-3-pro-image-preview:generateContent?key=<GEMINI_KEY>" \
-H "Content-Type: application/json" \
-d '{"contents":[{"role":"user","parts":[{"text":"<PROMPT>"}]}],
"generationConfig":{"responseModalities":["TEXT","IMAGE"]}}' \
--max-time 180 -o /tmp/gemini_resp.json
# 从 resp 中提取 candidates[].content.parts[].inlineData.data (base64) 落盘 PNG
gpt-image-2 直出(需有效 vip_2_image Key):
curl -s -X POST "https://www.micuapi.ai/v1/images/generations" \
-H "Authorization: Bearer <GPT_KEY>" -H "Content-Type: application/json" \
-d '{"model":"gpt-image-2","prompt":"<PROMPT>","size":"1024x1024","n":1,"response_format":"b64_json"}' \
--max-time 180
# 响应 data[0].b64_json 或 data[0].url
识别图片(v2,走代理,自动回退):
curl -s -X POST "http://localhost:8230/api/vision" -H "Content-Type: application/json" \
-d '{"image_b64":"<BASE64>","mime":"image/png","engine":"gpt-5.6-luna",
"api_keys":{"gemini":"<KEY>","gpt":"<KEY>"}}' --max-time 200
申请 API Key(推荐)
本技能依赖 AI 图像 API(micuapi.ai)。未注册可在此免费申请 Key,注册后在工作台「设置」页粘贴即可使用:
👉 申请地址:https://www.micuapi.ai/sign-up?aff=dp17
支持 Gemini 原生图像端点与 gpt-image-2 Images API 双引擎,按量计费。
API Key(存于工作台 localStorage,勿写入 git)
- Gemini Key / gpt-image-2 Key:不在源码中提供。请通过上方链接申请,启动工作台后在「设置」页填写,或通过受控环境变量/本地密钥管理器注入。
- gpt-image-2 Key:不在源码中提供。需使用具备对应模型分组权限的有效 Key,并在工作台「设置」页填写。
- Key 仅存于浏览器 localStorage 或本机环境,不得提交到 Git;校验端点:
GET /v1/models(带 Bearer 头)。
关键技术事实(实测确认)
- Gemini 模型不能走 OpenAI 图像端点:
/v1/images/generations只支持 imagen 系列,gemini 模型会报not supported model for image generation。Gemini 必须走/v1beta/models/{model}:generateContent?key=原生端点。 - Gemini 响应格式:
candidates[].content.parts[].inlineData(camelCase)或inline_data(snake_case)都可能出现,mime 为 image/jpeg / image/png,data 是 base64。 - gpt-image-2 编辑:
POST /v1/images/editsmultipart;image字段传原图文件,mask字段传 PNG(alpha=0 透明区 = 修改区,alpha=255 = 保留),mask 尺寸必须与原图一致。 - gpt-image-2 多图融合:同
/v1/images/edits,多图用字段名image[](每张 append 一次),2-10 张,总字节 ≤ 10MB。旧generations + image_urls已被AI 图像静默忽略(会返回 image_tokens=0),不要用。 - 多图融合 prompt 前缀(防拼贴):
Reference images are provided. Synthesize their visual elements (style, palette, composition, subjects) into ONE single new image per the instruction below. Do NOT collage, tile, or montage the references side-by-side unless explicitly asked.\n\nInstruction:\n{用户指令} - Gemini 遮罩编辑替代方案(工作台已实现):把遮罩笔触以 50% 透明红色叠加到原图上导出,配合指令「红色高亮区域需修改,其余像素保持不变」。效果弱于原生 mask 但可用。
- 尺寸规则(gpt-image-2):宽高 16 倍数、最长边 ≤3840、长宽比 ≤3:1、总像素 655,360–8,294,400;2K/4K 自动切
gpt-image-2-openai并强制 n=1 串行。 - n>1 的正确姿势:客户端循环 n 次每次 n=1(MCP 官方做法),不要一次传 n=N。
- 502 SSL EOF 根因:Python urllib TLS 指纹被 CF 拦截 → 代理一律用系统 curl 转发(见上方 v2 章节)。验证 curl 与 urllib 差异的最小复现:同一 349KB 带图 JSON,curl 成功 / urllib
UNEXPECTED_EOF_WHILE_READING。 - gpt-5.6-luna:OpenAI 兼容 vision 模型,走
/v1/chat/completions+image_urldata URL;当前 Gemini Key 分组无 channel(503),需 vip_2_image 分组 Key;识别服务端已实现自动回退 gemini-3-pro-image-preview。 - Gemini 背景移除不保证直接返回透明 PNG:即使提示词明确要求
alpha=0和 PNG,gemini-3-pro-image-preview仍可能返回image/jpeg(实测为均匀 RGB 灰底)。不得把 JPEG 改扩展名冒充透明 PNG。可靠流程:先让模型生成纯色均匀背景的高质量主体图,再用边界连通区域分割生成真实 RGBA PNG。推荐算法:取图像四周 20px 的中位色为背景色;计算 RGB 欧氏距离;从四边种子用scipy.ndimage.binary_propagation仅扩展到背景候选;对 3–28 色距做渐变 alpha 以保留抗锯齿;去除小于 20px 的孤立连通噪点;最后用 Pillow 保存 RGBA PNG,并强制验证mode=RGBA、alpha extrema(0,255)、透明像素数 > 0。
文件清单
~/.workbuddy/skills/image-gen-studio/
├── SKILL.md # 本文件
├── assets/
│ └── image-studio.html # 交互式工作台 v3(双引擎、遮罩画笔、多图栅格、资产画廊、识别弹窗、诊断弹窗、GitHub 同步)
├── scripts/
│ ├── proxy_server.py # 本地代理 v4.1(curl 转发 + 自动重试 + 资产库 API + /api/vision + 自动分类+GitHub 同步 + 单文件快速通道)
│ └── github_sync.py # GitHub 同步器 v4.1(Contents API 上传 + README 目录树重建 + --upload-only/--rebuild-readme 子命令)
└── references/
└── api-reference.md # API 端点 / 参数 / 响应格式速查
故障排查
| 症状 | 原因与处理 |
|---|---|
| 工作台打开但「未连接」 | 代理没启动 / 端口不对;重启 proxy_server.py |
| 401 Invalid token | Key 失效,去 micuapi.ai 令牌页换新,填入设置页 |
| HTTP 500 not supported model | Gemini 模型误走 OpenAI 端点;检查引擎选择 |
| CF 524 / 超时 | 4K 请求过大;gpt 引擎 4K 必须走 openai 高质量线路(slb 节点) |
| 生图只有文字没有图 | 响应 parts 只有 text;换 gemini-3-pro-image-preview 重试 |
| mask 无效 | mask 必须 PNG、尺寸与原图完全一致、透明区=修改区 |
| HTTP 502 SSL EOF / Remote end closed | 旧版 urllib 转发被 CF 拦截;确认代理为 v2(curl 转发),重启代理 |
| HTTP 403 code 1010 | curl 转发时 UA 被上游拦截;确认代理强制浏览器 UA(v2.1 起默认) |
| 503 model_not_found | 模型在当前 Key 分组无通道;换引擎/换 Key(识别会自动回退 gemini) |
| 资产不显示 | 检查 assets/ 目录存在、index.json 可读写;前端「🔄 刷新」 |