From yux-nano-banana
Generate images using OpenRouter API with Gemini models. Triggers on "generate image", "create image", "draw", "nano banana", "生成图片", "画图", "信息卡片".
npx claudepluginhub wuyuxiangx/yux-claude-hub --plugin yux-nano-bananaThis skill is limited to using the following tools:
Generate images using OpenRouter API with Google Gemini models.
Generates or edits images using Google Gemini API via nanobanana Python script. Supports prompts, aspect ratios, resolutions up to 4K, models like gemini-3.1-flash-image-preview, and image inputs for editing.
Generates or edits images using Google Gemini API via nanobanana.py Python script. Supports prompts, aspect ratios like 9:16, models such as gemini-3.1-flash, and resolutions up to 4K.
Generates and edits images using Google's Gemini Nano Banana Pro model (gemini-3-pro-image-preview) via bash API calls. Supports logos, product mockups, photo edits; requires GEMINI_API_KEY.
Share bugs, ideas, or general feedback.
Generate images using OpenRouter API with Google Gemini models.
Read references/image-data-safety.md before any API call. It contains safety rules, the fixed API response structure, and common mistakes to avoid.
Save generated images to the current working directory by default. If the user specifies a custom output path, use that instead (expand ~ to home directory; create directory if it doesn't exist using mkdir -p).
Run which curl jq base64 to confirm all tools are available. If any are missing, inform the user and stop.
Check if $OPENROUTER_API_KEY is set:
echo "${OPENROUTER_API_KEY:+set}"
If empty, inform the user: "Please set OPENROUTER_API_KEY in your environment." and stop immediately. Never prompt the user to enter the key inline.
Determine the operation type and parameters from the user's request:
When the user's request matches a style preset, wrap their content with the preset's prompt template. The user only needs to provide the topic/content — the style instructions are injected automatically.
infographic — Hand-drawn Infographic CardTrigger keywords: "infographic", "info card", "信息图", "信息卡片", "科普卡片", "手绘卡片", "インフォグラフィック", "인포그래픽"
Prompt template (wrap around the user's topic/content):
Create a hand-drawn style infographic card in landscape orientation (16:9 ratio).
Subject: {USER_CONTENT}
Style requirements:
- Hand-drawn / sketch illustration style with a warm, friendly, artisanal aesthetic
- Background: beige / cream color with subtle paper grain texture (NOT kraft paper, NO wrinkles or creases)
- NO border or frame around the edges of the card
- Clean, uncluttered layout with generous whitespace
- Use hand-drawn icons, diagrams, and illustrations as the primary way to convey information
- Minimal text — only short labels or annotations where necessary, the illustrations should tell the story
- Color palette: warm earth tones, muted pastels, with occasional accent colors for emphasis
- The overall feel should be like a beautifully illustrated notebook page — approachable and educational
When this preset is detected:
{USER_CONTENT} in the template with their topic| Shorthand | Model ID | When to use |
|---|---|---|
| flash | google/gemini-2.5-flash-image | User says "flash", "fast", "quick", "快速" |
| pro (default) | google/gemini-3-pro-image-preview | Default — highest quality |
If the user does not specify a model, use pro.
uname -s
This determines the base64 decode flag: -D on macOS (Darwin), -d on Linux.
For text-to-image generation:
curl -s -o /tmp/nano-banana-response.json -w "%{http_code}" \
https://openrouter.ai/api/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-d '{
"model": "<MODEL_ID>",
"messages": [
{
"role": "user",
"content": "<USER_PROMPT>"
}
]
}'
For image editing (user provides a source image):
First verify the source file exists and is a valid image:
ls "$SOURCE_IMAGE" && file --mime-type "$SOURCE_IMAGE"
If the file does not exist or is not an image, inform the user and stop.
Encode the source image to base64:
base64 < /path/to/source.png | tr -d '\n'
Store the result in a variable.
Then build the request with the image inline:
curl -s -o /tmp/nano-banana-response.json -w "%{http_code}" \
https://openrouter.ai/api/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-d '{
"model": "<MODEL_ID>",
"messages": [
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "data:<MIME_TYPE>;base64,<BASE64_DATA>"
}
},
{
"type": "text",
"text": "<EDITING_INSTRUCTIONS>"
}
]
}
]
}'
Important: Always use -o /tmp/nano-banana-response.json to save the response to a file. The response contains base64-encoded image data that can be very large and would be truncated in stdout. Use -w "%{http_code}" to capture the HTTP status code in stdout.
Important: For large base64 payloads (image editing), write the JSON body to a temp file first and use curl -d @/tmp/nano-banana-request.json to avoid shell argument length limits.
Check the HTTP status code returned by curl:
Validate image count (see references/image-data-safety.md for response structure):
jq -r '.choices[0].message.images | length' /tmp/nano-banana-response.json
0, null, or fails → safety-filtered. Inform the user and stop.1 or more → proceed to extraction.Extract the base64 data, strip the data-URI prefix, and decode — all in one pipeline redirected to a file. No intermediate temp file needed.
# OUTPUT_DIR defaults to "." (current directory). If user specified a custom path, expand ~ and ensure it exists:
# OUTPUT_DIR=$(echo "$USER_SPECIFIED_PATH" | sed "s|^~|$HOME|")
# mkdir -p "$OUTPUT_DIR"
FILENAME="$OUTPUT_DIR/nano-banana-$(date +%Y%m%d-%H%M%S).png"
jq -r '.choices[0].message.images[0].image_url.url' /tmp/nano-banana-response.json \
| sed 's|^data:image/[^;]*;base64,||' \
| base64 -D > "$FILENAME" # Use -d on Linux
Verify the file was created and has reasonable size (should be >100KB for a real image):
wc -c < "$FILENAME"
If the file is 0 bytes or very small, extraction failed — inform the user and stop.
rm -f /tmp/nano-banana-response.json /tmp/nano-banana-request.json
Display the result:
=== Image Generated ===
File: /path/to/nano-banana-20260329-143022.png
Size: 256 KB
Model: google/gemini-3-pro-image-preview
| HTTP Code | Error | Action |
|---|---|---|
| 401 | Invalid API key | Inform user, stop |
| 402 | Insufficient funds | Inform user, stop |
| 429 | Rate limited | Inform user, stop |
| 200 but no image | Safety filter | Inform user, stop. Do NOT explore alternative jq paths — the response structure is fixed |
| Network failure | Connection error | Inform user, stop |