| name | gpt-image |
| description | Generate images via OpenAI GPT Image (Azure gpt-image-2, OpenAI-direct
fallback on rate-limit). PREFER for: photorealistic / product / editorial
/ UI mockups, and any image whose embedded text must render correctly
(posters, infographics, logos). AVOID for: illustration / anime /
watercolor / 吉卜力 / hand-drawn, multi-reference editing, character
consistency — use nanobanana. Ambiguous with no style signal → this
skill silently, do NOT ask; offer a nanobanana regen if the aesthetic misses.
|
/gpt-image — Azure-first, OpenAI-fallback image generation
Generate images using GPT Image via Azure (preferred — user has contracted
compute at 10 RPM on deployment gpt-image-2), with automatic fallback
to OpenAI direct if Azure rate-limits.
When to use this skill vs nanobanana
| User intent | Skill |
|---|
| Photorealistic, editorial, UI mock, typographic, product shot | gpt-image |
| Logo with embedded text | gpt-image |
| Illustration, anime, reference-image editing, style transfer | nanobanana |
| Character consistency across scenes using reference images | nanobanana |
| Batch > 10 images per minute | gpt-image (it falls back to OpenAI direct, no throttle) |
If the user doesn't specify a style and no clear signal points either way,
default to gpt-image silently — do NOT ask (garbled text is worse than a
less-illustrative image); offer a nanobanana regen afterward if the
aesthetic misses.
Invocation
~/.claude/skills/gpt-image/generate.py "<prompt>" [options]
The script is a PEP 723 uv script with inline dependencies — no venv setup
needed. uv caches openai after first run.
Timeout: Azure generate latency is 100-125s, which straddles the Bash
tool's default 120s timeout — a plain call can return empty output and read
as a silent failure. Invoke generate.py with timeout=300000 (5 min) for
single images, ~420000 for --n batches.
Options
--size — any WxH with dims multiples of 16, long edge ≤ 3840, and total
pixels ≤ 8,294,400 (= 3840×2160; probed live 2026-07-21 — the API rejects
even budget+12k px with "exceeds the current pixel budget"). The script
auto-clamps oversized requests to the largest same-aspect valid size, so 4K
asks always succeed. Default 1024x1024. 4K/max presets: 3840x2160
(landscape UHD), 2160x3840 (portrait UHD), 2880x2880 (square max),
2480x3312 (3:4 portrait max) — note there is NO true 16MP 4096² tier
--n — number of images (default 1; batch throttled to 10 RPM on Azure)
--output — output directory (default ~/Downloads/gpt-image/)
--name — basename for output files (default gpt-image-<timestamp>)
--provider — auto (default, Azure → OpenAI fallback) | azure (Azure only) | openai (OpenAI direct only)
--azure-retries — 429 retries on Azure before fallback (default 3)
--edit PATH — image-to-image edit mode. When provided, routes to images.edit (input image + prompt → edited image) instead of images.generate. Repeatable for multi-image input: --edit a.png --edit b.png.
Examples (text → image)
~/.claude/skills/gpt-image/generate.py "editorial product shot of a matte-black espresso machine, soft window light, shallow depth of field" --size 1792x1024
~/.claude/skills/gpt-image/generate.py "minimalist poster for a jazz club, 1960s swiss style, bold typography reading 'BLUE NOTE'" --n 4 --output ./assets
~/.claude/skills/gpt-image/generate.py "cover art variations for Mio AI" --n 8 --provider openai
~/.claude/skills/gpt-image/generate.py "retry this one on Azure only" --provider azure
Examples (image + text → edited image)
~/.claude/skills/gpt-image/generate.py "replace the background with a cozy library, keep the cat and pose unchanged" --edit ./cat.png --size 1024x1792
~/.claude/skills/gpt-image/generate.py "transform into a Golden British Shorthair × Munchkin hybrid — plush golden fur, short legs kept" --edit ./munchkin.png --name hybrid
~/.claude/skills/gpt-image/generate.py "draw this person in this pose" --edit ./person.png --edit ./pose.png
Azure latency: edit ~42s, generate ~100-125s (as of 2026-04, eastus2). Edit is actually faster because much of the composition comes from the input image.
Rate-limit behaviour
- Azure: 10 RPM. Batch mode sleeps 7s between requests for headroom.
- On 429: exponential backoff (5s → 10s → 20s) for
--azure-retries
attempts, then falls through to OpenAI direct if OPENAI_API_KEY is set.
- OpenAI direct: 2 retries on 429 before bailing.
- Sticky fallback: once the Azure batch has fallen over to OpenAI for
one image, the remaining batch stays on OpenAI.
Credentials setup (one-time per machine)
The script reads credentials from environment variables first, then from
~/.config/gpt-image/credentials. Env vars win.
Option 1 — shell environment (preferred for scripting)
Add to ~/.zshrc:
export AZURE_OPENAI_API_KEY="<azure-key>"
export AZURE_OPENAI_ENDPOINT="https://xingf-mnqrf4mc-eastus2.cognitiveservices.azure.com"
export AZURE_OPENAI_DEPLOYMENT="gpt-image-2"
export AZURE_OPENAI_MODEL="gpt-image-2"
export AZURE_OPENAI_API_VERSION="2025-04-01-preview"
export OPENAI_API_KEY="<openai-direct-key>"
Option 2 — credentials file (preferred for one-off machines)
mkdir -p ~/.config/gpt-image
cat > ~/.config/gpt-image/credentials <<'EOF'
AZURE_OPENAI_ENDPOINT=https://xingf-mnqrf4mc-eastus2.cognitiveservices.azure.com
AZURE_OPENAI_DEPLOYMENT=gpt-image-2
AZURE_OPENAI_MODEL=gpt-image-2
AZURE_OPENAI_API_VERSION=2025-04-01-preview
AZURE_OPENAI_API_KEY=<azure-key>
OPENAI_API_KEY=<openai-direct-key>
EOF
chmod 600 ~/.config/gpt-image/credentials
Azure deployment vs model name — two names that Azure distinguishes:
- Deployment name (
AZURE_OPENAI_DEPLOYMENT) is what YOU named the deployment in
Azure portal. It goes in the URL path.
- Model name (
AZURE_OPENAI_MODEL) is what Azure internally calls the underlying
model. It goes in the request body. For the gpt-image-2 family, Azure typically
names the model gpt-image-2 regardless of what you named the deployment.
If you pass the deployment name where the model name is expected, Azure's edit
endpoint returns "The model 'X' does not exist" — even though the deployment
does exist. Get the real model name via:
az cognitiveservices account deployment show \
--name <resource> --resource-group <rg> \
--deployment-name <deployment> \
--query "properties.model.name" -o tsv
If only AZURE_OPENAI_API_KEY is set, fallback is disabled — rate-limit
errors surface directly. If only OPENAI_API_KEY is set, Azure is skipped
entirely.
Output
The script prints the path of each saved PNG to stdout (one per line),
which makes it easy to pipe into subsequent tools:
~/.claude/skills/gpt-image/generate.py "prompt" --n 3 | xargs open
Prompting tips
GPT Image is strongest when you give it:
- Subject + context: "a stoic robot barista in a futuristic cafe on Mars"
- Camera/framing: "low-angle shot, shallow depth of field (f/1.8)"
- Lighting: "golden hour backlight", "soft window light, 4500K"
- Style: "1990s product photography", "editorial, Magnum photos aesthetic"
- Typography (when needed): spell the exact text in quotes, specify font style and placement — e.g.,
text reading "URBAN EXPLORER" at the top, bold, white, sans-serif
For typography/text integration, GPT Image is usually better than Gemini.
For reference-image editing, use nanobanana instead.
Repaint over a draft, don't generate from text: for infographics, charts,
and diagrams, text-prompt-only generation is unreliable. Build the structure
first (matplotlib / hand-SVG / a rough render), pass it via --edit draft.png, and let GPT Image improve the presentation while preserving the
title and annotation text.
中文文字排版纪律 (CJK text discipline)
Any prompt that renders Chinese text MUST end with this suffix, appended
verbatim (prompt + SUFFIX — a hard invariant you concatenate every time,
never trust the model to remember it):
禁止:文字重叠、文字压在复杂图像上、伪汉字乱码、逐字竖排英文、
超过两种字体、页面四边贴字无留白、装饰元素盖过标题、每页超过 5 个信息块。
- >30 字正文 → 留位策略: image models cannot reliably render long CJK
body text. Have the model draw only the layout and visuals, leave the text
zone blank, and overlay real text in post (PPT / image editor). This is the
only reliable approach for long Chinese copy.
- 成套图 cover-first: generate the cover first (it locks the style), then
1 content image to verify style match, then batch the rest — same style
brief injected into every prompt, only content parameters vary. Re-check
against the cover every ~5 images; on drift, regenerate reusing the cover
prompt's style paragraph.
- 中文横排;标点不出现在行首;中英混排时英文占比 ≤ 20%。
- Prompt 里的内部约束不要直接喂给模型: any constraint in a prompt
("public data only", "no logo") is frequently rendered as visible text on
the image. Separate rules from copy — phrase constraints as "Do not render
any text about X" AND enumerate the exact visible strings the model is
allowed to draw.