Appearance
用 Codex 生成图片(gpt-image-2)
费用说明: 通过 CodexZH 使用 gpt-image-2,每生成一张图片计费 $0.5,按次从周额度中扣除。
⚠️ 风险提示: 使用这种方式,可能会出现你只发了一个需求,但是生图的请求掉了几次。这是 Agent 自己掉的,它在生成完之后会自己检查,如果觉得不合适,会重新再去生成。所以,你会看到使用记录里面有好几条的调用。如果你只需要让它每一次只调用一次,那么请参考 AI HUB API 网页生图教程 使用。
codexzh-image 是平台自带的画图技能。装好后在 Codex 里输入 /image 就能调用,支持文生图(按文字描述出图)和图生图(改一张已有的图)。
💡 懒人小贴士: 不想手动建文件,可以让 Codex 自己装。把下面这句话复制给 Codex,它会读取本教程并自动配置好:
请打开这个页面 https://docs.codexzh.com/codex/image-2 ,按照里面"手动创建"一节,把 codexzh-image 技能的 4 个文件分别创建到对应位置(SKILL.md、openai-image.sh、openai-image.ps1,以及 ~/.codex/.env),内容严格照页面里的代码块填写。.env 里的 api_key 先留占位,最后提醒我换成自己的密钥。
技能要用到的文件
技能由 4 个文件组成,分别放在下面这些位置:
~/.codex/
├── .env # 接口地址和密钥
└── skills/
└── codexzh-image/
├── SKILL.md # 技能说明
└── scripts/
├── openai-image.sh # macOS / Linux 脚本
└── openai-image.ps1 # Windows 脚本~/.codex 这个目录在哪里?
上面的 ~/.codex 是个简写,~ 代表你电脑的「用户主目录」,.codex 是它下面一个以点开头的隐藏文件夹。它通常不会直接显示出来,按下面的方法找到它:
Mac:
- 打开「访达(Finder)」。
- 按下快捷键
Command + Shift + G,会弹出一个跳转输入框。 - 输入
~/.codex后回车,即可直接进入该目录。 - 如果提示文件夹不存在,说明还没创建——可以先按上面的目录结构手动新建,或直接交给 Codex 自动创建。
小贴士:在访达里按
Command + Shift + .(点号)可以切换显示/隐藏以点开头的文件。
Windows:
- 打开「文件资源管理器」。
- 点击顶部的地址栏,输入
%USERPROFILE%\.codex后回车,即可进入该目录。 (%USERPROFILE%就是你的用户文件夹,一般是C:\Users\你的用户名。) - 如果提示找不到,说明
.codex文件夹还没创建——在用户文件夹下手动新建一个名为.codex的文件夹即可,或直接交给 Codex 自动创建。
小贴士:若要直接看到隐藏文件夹,可在资源管理器顶部「查看 → 显示 → 隐藏的项目」中打开。
手动安装
按上面的目录结构新建这 4 个文件,再展开下方对应区块,把内容复制进去保存。
装完后,把
~/.codex/.env里的api_key改成你自己的密钥(sk-...)。如果这个文件里已有http_proxy等代理设置,保留即可,互不影响。
~/.codex/.env —— 接口地址和密钥:
base_url=https://api.codexzh.com/v1
api_key=sk-xxx~/.codex/skills/codexzh-image/SKILL.md(点击展开)
markdown
---
name: codexzh-image
description: 用 OpenAI 兼容接口(curl 命令行)生成或编辑图片。当用户想"生成图片/画一张图/文生图/做张配图/帮我画/create an image/generate image",或"改图/图生图/编辑这张图/换背景/给图片加东西/edit image"时使用本技能。它读取 ~/.codex/.env 里的 base_url 与 api_key,用 curl 调接口;Base64 结果会解码保存到本地,URL 结果会下载到 --out。无需安装任何 Python/环境。只要用户提到生成图片、画图、改图、图像编辑,即使没说"用 OpenAI 接口",也应优先考虑用本技能。
---
# OpenAI 图像生成 / 编辑(curl 方式)
通过 OpenAI 兼容的 `/images/generations`(文生图)和 `/images/edits`(图生图 / 编辑)接口生成图片。
所有调用都用 `curl`(Windows 用 PowerShell)。如果接口返回非空 `b64_json`,脚本会解码并保存到本地;如果没有非空 `b64_json` 但有 `url`,脚本会下载到 `--out` 指定路径。**不依赖 Python,无需装环境。**
技能自带两个脚本,直接调用即可,不要重写:
- `scripts/openai-image.sh` —— macOS / Linux
- `scripts/openai-image.ps1` —— Windows
## 工作流程
### 第 1 步:确认配置存在
脚本会读取 `~/.codex/.env`(Windows:`%USERPROFILE%\.codex\.env`)里的两行:
```
base_url=https://api.xbai.top/v1
api_key=sk-你的密钥
```
先快速检查这两个键是否存在:
```bash
grep -E '^\s*(base_url|api_key)\s*=' ~/.codex/.env 2>/dev/null
```
**如果缺少 base_url 或 api_key**,引导用户配置——告诉用户在 `~/.codex/.env` 里加上这两行,并给出 base_url 的两个推荐选项:
- `https://api.xbai.top/v1`
- `https://api.codexzh.com/v1`
- 如果用户用的是别的中转站 / 官方接口,让用户把自己的 base_url 给你,或自行填写。
`api_key` 必须由用户自己提供(不要编造)。可以用 AskUserQuestion 让用户选 base_url,但密钥一定让用户自己填进文件,确认后再继续。
> 注意:该 `.env` 里可能已有 http_proxy 等代理设置,互不影响,保留即可。
### 第 2 步:判断任务类型并收集参数
- **文生图(generate)**:只有文字描述 → 用 `generate`。
- **图生图 / 编辑(edit)**:用户给了一张或多张已有图片,想改它 → 用 `edit`,把图片路径作为 `--image` 传入。
需要的参数:
- `--prompt`(必填):图像描述,尽量把用户的意图写清楚、具体。
- `--model`:默认 `gpt-image-2`。用户指定别的就用别的。
- `--size`:默认 `1024x1024`。gpt-image 还支持 `1536x1024`(横)、`1024x1536`(竖)、`auto`。
- `--n`:生成数量,默认 1。
- `--out`:图片保存路径,默认当前目录 `image-时间戳.png`。多张时自动加 `_1`、`_2` 后缀。URL 返回通常有有效期,脚本会立即下载到该路径。
### 第 3 步:调用脚本
**macOS / Linux:**
```bash
# 文生图
bash ~/.codex/skills/codexzh-image/scripts/openai-image.sh generate \
--prompt "一只戴贝雷帽、坐在木桌上的小水獭,柔和光线" \
--size 1024x1024 --out ./otter.png
# 图生图 / 编辑(可多张 --image,可选 --mask 局部重绘)
bash ~/.codex/skills/codexzh-image/scripts/openai-image.sh edit \
--prompt "把背景换成下雪的雪山" \
--image ./otter.png --out ./otter-snow.png
```
**Windows(PowerShell):**
```powershell
# 文生图
powershell -ExecutionPolicy Bypass -File "$HOME\.codex\skills\codexzh-image\scripts\openai-image.ps1" `
generate -Prompt "一只戴贝雷帽的小水獭" -Out .\otter.png
# 图生图 / 编辑
powershell -ExecutionPolicy Bypass -File "$HOME\.codex\skills\codexzh-image\scripts\openai-image.ps1" `
edit -Prompt "把背景换成雪山" -Image .\otter.png -Out .\otter-snow.png
```
> Windows 的 `edit`(图生图)依赖 PowerShell 7+ 的 `Invoke-RestMethod -Form`。若用户是自带的 PowerShell 5,文生图可用,图生图建议在 macOS/Linux 上或装 PowerShell 7。
### 第 4 步:报告结果
脚本会把 Base64 或 URL 返回的图片保存到本地,并打印 `✅ 已保存:路径`。把保存的文件路径告诉用户,并尽量展示本地图片。
如果下载或解码失败,脚本会退出并打印明确错误;不要把 0B 文件当作成功结果。
## 接口与参数速查(来自 OpenAI Images API)
| 接口 | 方法 | 用途 | 关键参数 |
| --------------------- | ---------------- | -------------------- | ------------------------------------------------------------ |
| `/images/generations` | POST (JSON) | 文生图 | `model` `prompt` `n` `size` `quality` |
| `/images/edits` | POST (multipart) | 图生图 / 编辑 / 扩展 | `image[]`(必填,可多张)`prompt` `mask`(可选,局部重绘)`n` `size` |
要点:
- `gpt-image` 系列接口通常返回 `b64_json`(base64),脚本会自动解码落地;`dall-e` 系列或部分中转站可能返回 `url`,脚本会立即下载保存。两种都已兼容。
- `dall-e-3` **不支持** `/images/edits` 编辑端点;要做图生图请用 `gpt-image-2`(默认)或 `dall-e-2`。
- `mask`(掩码):透明区域表示要重绘的位置,必须是与原图同尺寸的 PNG。仅在用户要"局部修改某个区域"时才用。
## 常见问题
- **报错"未找到 base_url 或 api_key"** → 回到第 1 步引导用户在 `.env` 里补全。
- **接口报错(余额 / 模型不存在 / 鉴权失败)** → 脚本会原样打印接口返回的 error,把它转述给用户,常见是 api_key 错误、余额不足或该中转站不支持所选 model。
- **保存出 0B 文件或下载失败** → 旧脚本可能把空 `b64_json` 当成功;现在会优先使用非空 `b64_json`,否则回退下载 `url`,并在文件为空时显式失败。
- **想换模型** → 加 `--model 模型名`,例如 `--model dall-e-3`(仅文生图)。~/.codex/skills/codexzh-image/scripts/openai-image.sh(点击展开)
bash
#!/usr/bin/env bash
# openai-image.sh — 通过 OpenAI 兼容接口用 curl 生成 / 编辑图片
# 依赖:curl、base64、grep、sed(macOS / Linux 自带,无需安装任何环境)
#
# 用法:
# 生成(文生图):
# openai-image.sh generate --prompt "一只戴贝雷帽的小水獭" \
# [--model gpt-image-2] [--size 1024x1024] [--n 1] [--quality auto] [--out 路径.png]
# 编辑 / 图生图:
# openai-image.sh edit --prompt "把背景换成雪山" --image in.png \
# [--image 第二张.png ...] [--mask mask.png] \
# [--model gpt-image-2] [--size 1024x1024] [--n 1] [--out 路径.png]
#
# 配置:默认读取 $HOME/.codex/.env 中的 base_url 和 api_key
# (可用环境变量 OPENAI_IMAGE_ENV 覆盖配置文件路径)
set -euo pipefail
ENV_FILE="${OPENAI_IMAGE_ENV:-$HOME/.codex/.env}"
DEFAULT_MODEL="gpt-image-2"
err() { printf '%s\n' "$*" >&2; }
# ---------- 读取配置 ----------
read_cfg() {
# 读取 key=value,忽略前后空白与包裹的引号;找不到时安全返回空
local key="$1" line
[ -f "$ENV_FILE" ] || return 0
line="$(grep -E "^[[:space:]]*${key}[[:space:]]*=" "$ENV_FILE" 2>/dev/null | head -1)" || return 0
[ -n "$line" ] || return 0
line="${line#*=}" # 去掉 key= 前缀
line="$(printf '%s' "$line" | sed -E 's/^[[:space:]]+//; s/[[:space:]]+$//')" # 先去首尾空白
line="$(printf '%s' "$line" | sed -E 's/^"(.*)"$/\1/; s/^'\''(.*)'\''$/\1/')" # 再去包裹引号
printf '%s' "$line"
}
BASE_URL="$(read_cfg base_url)"
API_KEY="$(read_cfg api_key)"
if [ -z "$BASE_URL" ] || [ -z "$API_KEY" ]; then
err "❌ 未在 $ENV_FILE 中找到 base_url 或 api_key。"
err ""
err "请在该文件中补充以下两行(任选一个 base_url,或填你自己的):"
err " base_url=https://api.xbai.top/v1"
err " api_key=sk-你的密钥"
err ""
err "可选的另一个站点: base_url=https://api.codexzh.com/v1"
exit 2
fi
# 去掉 base_url 结尾多余的斜杠
BASE_URL="${BASE_URL%/}"
# ---------- 解析参数 ----------
MODE="${1:-}"; shift || true
PROMPT=""; MODEL="$DEFAULT_MODEL"; SIZE="1024x1024"; N="1"; QUALITY=""; OUT=""
MASK=""; IMAGES=()
while [ $# -gt 0 ]; do
case "$1" in
--prompt) PROMPT="$2"; shift 2 ;;
--model) MODEL="$2"; shift 2 ;;
--size) SIZE="$2"; shift 2 ;;
--n) N="$2"; shift 2 ;;
--quality) QUALITY="$2"; shift 2 ;;
--out) OUT="$2"; shift 2 ;;
--mask) MASK="$2"; shift 2 ;;
--image) IMAGES+=("$2"); shift 2 ;;
*) err "未知参数:$1"; exit 2 ;;
esac
done
[ -n "$PROMPT" ] || { err "缺少 --prompt"; exit 2; }
# 输出文件名(默认按时间戳放当前目录)
if [ -z "$OUT" ]; then
OUT="./image-$(date +%Y%m%d-%H%M%S).png"
fi
OUT_DIR="$(dirname "$OUT")"
mkdir -p "$OUT_DIR"
TMP="$(mktemp -t openai-image.XXXXXX.json)"
trap 'rm -f "$TMP"' EXIT
# ---------- JSON 字符串转义(仅生成接口用)----------
json_escape() {
printf '%s' "$1" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' | tr '\n' ' '
}
# ---------- 处理响应里的图片 ----------
output_path_for_index() {
local i="$1" name ext base suffix
name="${OUT##*/}"
suffix=""
if [ "$name" != "${name%.*}" ]; then
ext="${OUT##*.}"
base="${OUT%.*}"
suffix=".$ext"
else
base="$OUT"
fi
if [ "$i" -eq 0 ]; then
printf '%s' "$OUT"
else
printf '%s_%s%s' "$base" "$i" "$suffix"
fi
}
json_unescape_url() {
# curl only needs the common JSON escapes that appear in URLs from these APIs.
printf '%s' "$1" | sed -E 's#\\/#/#g; s#\\u0026#\&#g'
}
commit_image_file() {
local tmp_file="$1" final_file="$2"
if [ ! -s "$tmp_file" ]; then
rm -f "$tmp_file"
err "❌ 保存失败:生成的文件为空:$final_file"
return 1
fi
mv "$tmp_file" "$final_file"
printf '✅ 已保存:%s\n' "$final_file"
}
save_b64_image() {
local b64="$1" final_file="$2" tmp_file
tmp_file="$(mktemp "${final_file}.XXXXXX")"
if printf '%s' "$b64" | base64 -d > "$tmp_file" 2>/dev/null; then
:
elif printf '%s' "$b64" | base64 -D > "$tmp_file" 2>/dev/null; then
:
else
rm -f "$tmp_file"
err "❌ Base64 解码失败:$final_file"
return 1
fi
commit_image_file "$tmp_file" "$final_file"
}
save_url_image() {
local url="$1" final_file="$2" tmp_file
tmp_file="$(mktemp "${final_file}.XXXXXX")"
if ! curl -fsSL "$url" -o "$tmp_file"; then
rm -f "$tmp_file"
err "❌ URL 下载失败:$url"
return 1
fi
commit_image_file "$tmp_file" "$final_file"
}
extract_json_field() {
local obj="$1" field="$2" match
match="$(
printf '%s' "$obj" \
| grep -o "\"$field\"[[:space:]]*:[[:space:]]*\"[^\"]*\"" \
| head -1
)" || true
[ -n "$match" ] || return 0
printf '%s' "$match" | sed -E "s/.*\"$field\"[[:space:]]*:[[:space:]]*\"//; s/\"$//"
}
save_outputs() {
local resp="$1" compact objects i obj b64 url f
compact="$(tr -d '\n' < "$resp")"
objects="$(printf '%s' "$compact" | grep -o '{[^{}]*}' || true)"
i=0
if [ -n "$objects" ]; then
while IFS= read -r obj; do
[ -n "$obj" ] || continue
b64="$(extract_json_field "$obj" "b64_json")"
url="$(extract_json_field "$obj" "url")"
f="$(output_path_for_index "$i")"
if [ -n "$b64" ]; then
save_b64_image "$b64" "$f" || exit 1
i=$((i+1))
elif [ -n "$url" ]; then
url="$(json_unescape_url "$url")"
save_url_image "$url" "$f" || exit 1
i=$((i+1))
fi
done <<EOF
$objects
EOF
fi
if [ "$i" -eq 0 ]; then
err "❌ 接口返回异常,原始响应:"
cat "$resp" >&2
exit 1
fi
}
# ---------- 调用接口 ----------
case "$MODE" in
generate)
esc="$(json_escape "$PROMPT")"
body="$(printf '{"model":"%s","prompt":"%s","n":%s,"size":"%s"' "$MODEL" "$esc" "$N" "$SIZE")"
[ -n "$QUALITY" ] && body="${body},\"quality\":\"${QUALITY}\""
body="${body}}"
curl -sS "$BASE_URL/images/generations" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d "$body" -o "$TMP"
;;
edit)
[ "${#IMAGES[@]}" -gt 0 ] || { err "edit 模式至少需要一个 --image"; exit 2; }
args=( -sS "$BASE_URL/images/edits"
-H "Authorization: Bearer $API_KEY"
-F "model=$MODEL"
-F "prompt=$PROMPT"
-F "n=$N"
-F "size=$SIZE" )
for img in "${IMAGES[@]}"; do
[ -f "$img" ] || { err "图片不存在:$img"; exit 2; }
# gpt-image 系列用 image[],多图支持;dall-e-2 也兼容
args+=( -F "image[]=@${img}" )
done
[ -n "$MASK" ] && args+=( -F "mask=@${MASK}" )
[ -n "$QUALITY" ] && args+=( -F "quality=$QUALITY" )
curl "${args[@]}" -o "$TMP"
;;
*)
err "用法:openai-image.sh {generate|edit} --prompt \"...\" [选项]"
exit 2
;;
esac
# ---------- 出错检测 ----------
if grep -q '"error"' "$TMP" && ! grep -q '"b64_json"\|"url"' "$TMP"; then
err "❌ 接口报错:"
cat "$TMP" >&2
exit 1
fi
save_outputs "$TMP"~/.codex/skills/codexzh-image/scripts/openai-image.ps1(点击展开)
powershell
<#+
openai-image.ps1 - Generate or edit images through an OpenAI-compatible Images API.
Configuration is read from $HOME\.codex\.env by default, or from OPENAI_IMAGE_ENV when set.
Required keys:
base_url=https://api.example.com/v1
api_key=sk-...
Optional proxy keys are also honored:
http_proxy=http://127.0.0.1:7890
https_proxy=http://127.0.0.1:7890
Examples:
powershell -ExecutionPolicy Bypass -File openai-image.ps1 generate -Prompt "A small otter" -Out .\otter.png
powershell -ExecutionPolicy Bypass -File openai-image.ps1 edit -Prompt "Change background to snow" -Image .\otter.png -Out .\otter-snow.png
#>
param(
[Parameter(Position = 0, Mandatory = $true)]
[ValidateSet('generate', 'edit')]
[string]$Mode,
[string]$Prompt,
[string]$Model = 'gpt-image-2',
[string]$Size = '1024x1024',
[int]$N = 1,
[string]$Quality = '',
[string]$Out = '',
[string]$Image = '',
[string]$Image2 = '',
[string]$Mask = ''
)
$ErrorActionPreference = 'Stop'
$EnvFile = if ($env:OPENAI_IMAGE_ENV) { $env:OPENAI_IMAGE_ENV } else { Join-Path $HOME '.codex\.env' }
function Read-Cfg([string]$Key) {
if (-not (Test-Path -LiteralPath $EnvFile)) { return '' }
foreach ($line in Get-Content -LiteralPath $EnvFile) {
if ($line -match "^\s*$([regex]::Escape($Key))\s*=\s*(.*)$") {
return $Matches[1].Trim().Trim('"').Trim("'")
}
}
return ''
}
function Set-OptionalProxy([string]$Key, [string]$EnvNameLower, [string]$EnvNameUpper) {
$value = Read-Cfg $Key
if ($value) {
[Environment]::SetEnvironmentVariable($EnvNameLower, $value, 'Process')
[Environment]::SetEnvironmentVariable($EnvNameUpper, $value, 'Process')
}
}
$BaseUrl = Read-Cfg 'base_url'
$ApiKey = Read-Cfg 'api_key'
if (-not $BaseUrl -or -not $ApiKey) {
Write-Error @"
Missing base_url or api_key in $EnvFile.
Add both lines, for example:
base_url=https://api.xbai.top/v1
api_key=sk-your-key
"@
exit 2
}
if (-not $Prompt) {
Write-Error 'Missing -Prompt.'
exit 2
}
if ($N -lt 1) {
Write-Error '-N must be at least 1.'
exit 2
}
$BaseUrl = $BaseUrl.TrimEnd('/')
Set-OptionalProxy 'http_proxy' 'http_proxy' 'HTTP_PROXY'
Set-OptionalProxy 'https_proxy' 'https_proxy' 'HTTPS_PROXY'
if (-not $Out) {
$Out = ".\image-$(Get-Date -Format yyyyMMdd-HHmmss).png"
}
$OutDir = Split-Path -Parent $Out
if ($OutDir -and -not (Test-Path -LiteralPath $OutDir)) {
New-Item -ItemType Directory -Path $OutDir | Out-Null
}
$Headers = @{ Authorization = "Bearer $ApiKey" }
function Get-OutputPath([int]$Index) {
$extension = [System.IO.Path]::GetExtension($Out)
$baseName = if ($extension) { $Out.Substring(0, $Out.Length - $extension.Length) } else { $Out }
if ($Index -eq 0) { return $Out }
if ($extension) { return "${baseName}_$Index$extension" }
return "${baseName}_$Index"
}
function Commit-ImageFile([string]$TempFile, [string]$FinalFile) {
if (-not (Test-Path -LiteralPath $TempFile) -or (Get-Item -LiteralPath $TempFile).Length -le 0) {
Remove-Item -LiteralPath $TempFile -Force -ErrorAction SilentlyContinue
throw "Save failed: generated file is empty for $FinalFile."
}
Move-Item -LiteralPath $TempFile -Destination $FinalFile -Force
Write-Host "Saved: $FinalFile"
}
function Save-B64Image([string]$B64, [string]$FinalFile) {
$tempFile = [System.IO.Path]::GetTempFileName()
try {
[System.IO.File]::WriteAllBytes($tempFile, [System.Convert]::FromBase64String($B64))
} catch {
Remove-Item -LiteralPath $tempFile -Force -ErrorAction SilentlyContinue
throw "Base64 decode failed for $FinalFile. $($_.Exception.Message)"
}
Commit-ImageFile $tempFile $FinalFile
}
function Save-UrlImage([string]$Url, [string]$FinalFile) {
$tempFile = [System.IO.Path]::GetTempFileName()
$client = New-Object System.Net.WebClient
try {
$client.DownloadFile($Url, $tempFile)
} catch {
Remove-Item -LiteralPath $tempFile -Force -ErrorAction SilentlyContinue
throw "URL download failed for $Url. $($_.Exception.Message)"
} finally {
$client.Dispose()
}
Commit-ImageFile $tempFile $FinalFile
}
function Save-Outputs($Data) {
$savedCount = 0
foreach ($item in @($Data)) {
if ($null -eq $item) { continue }
$outputFile = Get-OutputPath $savedCount
$b64 = if ($null -ne $item.b64_json) { [string]$item.b64_json } else { '' }
$url = if ($null -ne $item.url) { [string]$item.url } else { '' }
if ($b64.Trim().Length -gt 0) {
Save-B64Image $b64 $outputFile
$savedCount++
continue
}
if ($url.Trim().Length -gt 0) {
Save-UrlImage $url.Trim() $outputFile
$savedCount++
continue
}
throw "API response item $($savedCount + 1) has no non-empty b64_json or url."
}
if ($savedCount -eq 0) {
throw 'API response did not contain image data.'
}
}
if ($Mode -eq 'generate') {
$bodyObject = @{
model = $Model
prompt = $Prompt
n = $N
size = $Size
}
if ($Quality) { $bodyObject.quality = $Quality }
$body = $bodyObject | ConvertTo-Json -Compress
$response = Invoke-RestMethod -Method Post -Uri "$BaseUrl/images/generations" -Headers $Headers -ContentType 'application/json' -Body $body
Save-Outputs $response.data
} elseif ($Mode -eq 'edit') {
if (-not $Image) {
Write-Error 'Edit mode requires -Image.'
exit 2
}
if (-not (Test-Path -LiteralPath $Image)) {
Write-Error "Image file not found: $Image"
exit 2
}
if ($Image2 -and -not (Test-Path -LiteralPath $Image2)) {
Write-Error "Image2 file not found: $Image2"
exit 2
}
if ($Mask -and -not (Test-Path -LiteralPath $Mask)) {
Write-Error "Mask file not found: $Mask"
exit 2
}
if ($PSVersionTable.PSVersion.Major -lt 7) {
Write-Error 'Edit mode requires PowerShell 7+ because Windows PowerShell 5 does not support Invoke-RestMethod -Form.'
exit 2
}
$form = @{
model = $Model
prompt = $Prompt
n = "$N"
size = $Size
}
$images = @(Get-Item -LiteralPath $Image)
if ($Image2) { $images += Get-Item -LiteralPath $Image2 }
$form['image[]'] = $images
if ($Mask) { $form['mask'] = Get-Item -LiteralPath $Mask }
if ($Quality) { $form['quality'] = $Quality }
$response = Invoke-RestMethod -Method Post -Uri "$BaseUrl/images/edits" -Headers $Headers -Form $form
Save-Outputs $response.data
}开始使用
四个文件就位后,重启 Codex,输入 /image 选择 codexzh-image 技能,再描述你想要的图片即可。效果如下:
