Gemini Imagen
Generate and edit images using Google's Gemini API. The environment variable GEMINI_API_KEY must be set.
Quick Reference
| Setting | Default | Options |
|---|---|---|
| Model | gemini-3.1-flash-image |
--model gemini-3-pro-image for production-quality finals |
| Resolution | 1K | 1K, 2K, 4K |
| Aspect Ratio | 1:1 | 1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9, 4:1, 1:4, 8:1, 1:8 |
Usage
uv run <skill-dir>/scripts/generate_image.py generate --prompt "a sunset" --filename "2026-02-21-14-30-00-sunset.jpg"
uv run <skill-dir>/scripts/generate_image.py edit --prompt "add clouds" --input-image photo.jpg --filename "2026-02-21-14-35-00-cloudy.jpg"
uv run <skill-dir>/scripts/generate_image.py compose --prompt "merge these scenes" --input-images a.jpg b.jpg --filename "2026-02-21-14-40-00-merged.jpg"
Run from the user's working directory so images save where expected, not in the skill directory.
Default Workflow
Follow a two-tier draft-iterate-final pattern:
- Draft (Flash, 1K): Use the default model (
gemini-3.1-flash-image) at 1K for rapid ideation. - Iterate: Adjust the prompt in small diffs. Use a new filename per run. For editing, keep the same
--input-image. - Final (Pro, 4K): When the prompt is locked, re-run with
--model gemini-3-pro-image --resolution 4Kfor production-quality output.
Resolution Options
| Flag | Approximate Size | When to Use |
|---|---|---|
--resolution 1K |
~1024px | Drafts, quick iteration |
--resolution 2K |
~2048px | Medium-quality deliverables |
--resolution 4K |
~4096px | Final output, print, high-res use |
Natural language mapping:
- No mention of resolution -> 1K
- "low resolution", "1080p", "1K" -> 1K
- "2K", "2048", "medium" -> 2K
- "high resolution", "hi-res", "4K", "ultra" -> 4K
The edit subcommand auto-detects resolution from the input image dimensions when --resolution is not provided.
Aspect Ratios
| Ratio | Use Case |
|---|---|
| 1:1 | Square (social media, icons) |
| 2:3 | Portrait photo standard |
| 3:2 | Landscape photo standard |
| 3:4 | Portrait display, presentation |
| 4:3 | Landscape display, presentation |
| 4:5 | Portrait photo (Instagram) |
| 5:4 | Landscape photo |
| 9:16 | Vertical video (Stories, Reels) |
| 16:9 | Horizontal video (YouTube) |
| 21:9 | Ultra-wide, panoramic |
| 4:1 | Extreme wide banner |
| 1:4 | Extreme tall banner |
| 8:1 | Ultra-wide strip |
| 1:8 | Ultra-tall strip |
Aspect ratio drift in edits: The model may change aspect ratio unexpectedly when editing. Add "Do not change the input aspect ratio" to the edit prompt, or supply a reference image at the desired dimensions.
API Key
The script checks for an API key in this order:
--api-keyargumentGEMINI_API_KEYenvironment variable
Preflight and Common Failures
Preflight Checklist
command -v uv # must exist
test -n "$GEMINI_API_KEY" # or pass --api-key
# For edit: verify input image exists
test -f <input-image-path>
Common Failures
| Error Message | Cause and Fix |
|---|---|
| "Error: No API key provided." | Set GEMINI_API_KEY or pass --api-key |
| "Error loading input image:" | Wrong path; verify the --input-image path exists |
| quota / permission / 403 | Wrong key, no API access, or quota exceeded |
Filename Convention
Pattern: yyyy-mm-dd-hh-mm-ss-name.jpg
- Timestamp: current date and time in 24-hour format
- Name: descriptive lowercase with hyphens, 1-5 words
- Extension:
.jpgby default (Gemini returns JPEG)
Examples:
2026-02-21-14-30-00-sunset.jpg2026-02-21-09-15-42-product-hero-shot.jpg2026-02-21-16-05-11-blue-gradient-bg.jpg
Prompt Templates
Generation
"Create an image of: <subject>. Style: <style>. Composition: <camera/shot>. Lighting: <lighting>. Background: <background>. Color palette: <palette>. Avoid: <list>."
Editing (preserve everything else)
"Change ONLY: <single change>. Keep identical: subject, composition/crop, pose, lighting, color palette, background, text, and overall style. Do not add new objects. If text exists, keep it unchanged."
Prompting Best Practices
Photorealistic: Include camera details -- lens type, lighting, angle, mood.
"A plate of sushi on a dark slate counter, shot with a 50mm f/1.4 lens, soft window light from the left, shallow depth of field, warm tones, overhead angle."
Stylized Art: Specify style explicitly -- kawaii, cel-shading, bold outlines.
"A fox sitting in a forest, kawaii style, soft pastels, thick black outlines, big expressive eyes, flat shading, no gradients."
Text in Images (Gemini strength): Gemini handles text rendering better than most image models — use it for logos, posters, diagrams, greeting cards, and text localization. Be explicit about font style, placement, and exact wording.
"A motivational poster with the text 'KEEP GOING' in bold white sans-serif centered on a dark blue gradient background."
Product Mockups: Describe lighting setup and surface.
"A white coffee mug on a marble countertop, studio lighting with a soft key light from the upper right and a fill light from the left, clean white background, slight reflection on the surface."
Advanced: Multi-Turn Refinement
The script runs single-turn calls. For iterative refinement within a single conversation, use the chat API directly:
from google.genai import types
chat = client.chats.create(
model="gemini-3.1-flash-image",
config=types.GenerateContentConfig(response_modalities=["TEXT", "IMAGE"]),
)
response = chat.send_message("Create a logo for 'Acme Corp'")
response = chat.send_message("Make the text bolder and add a blue gradient")
Advanced: Google Search Grounding
Use Google Search grounding to generate images informed by real-world data:
response = client.models.generate_content(
model="gemini-3.1-flash-image",
contents="Generate an image of the latest Tesla Model Y in a showroom",
config=types.GenerateContentConfig(
response_modalities=["TEXT", "IMAGE"],
tools=[{"google_search": {}}],
),
)
Note: Google Search grounding does not work with image-only response mode.
Advanced: Multiple Reference Images
The compose subcommand handles multi-image input (up to 14 images). For direct API usage:
from PIL import Image
images = [Image.open(p) for p in ["ref1.jpg", "ref2.jpg", "ref3.jpg"]]
contents = ["Combine these into a single panoramic scene"] + images
response = client.models.generate_content(
model="gemini-3.1-flash-image",
contents=contents,
config=config,
)
The API supports up to 14 input images per request.
File Format Notes
- Gemini returns JPEG by default -- always use
.jpgfor output filenames. - The script handles format automatically: a
.pngextension saves as PNG, anything else saves as JPEG. - To convert to PNG: use
--filenamewith a.pngextension. - Verification: run
file image.jpgto check the actual format on disk. - All generated images include SynthID watermarks embedded by the Gemini API.
When To Use
- When the user requests image generation, editing, or composition via Gemini
- When multi-image composition or specific aspect-ratio control is needed
- When the user mentions Gemini by name for image tasks
- When iterative prompt refinement with draft-iterate-final workflow is appropriate
Boundaries
- Not for non-Gemini image APIs (DALL-E, Stable Diffusion, Midjourney)
- Not for video generation or animation
- Not for image analysis or captioning without generation
- Skip 4K resolution during drafting — use 1K until the prompt is locked
Output
- Image files saved to the user's working directory with timestamped filenames (
yyyy-mm-dd-hh-mm-ss-name.jpg) - JPEG format by default; PNG when
.pngextension is specified - One file per generation/edit/compose call
Resources
scripts/generate_image.py— CLI for generate, edit, and compose subcommandsreferences/sample-prompts.md— use-case-specific prompt recipes for generation and editing
Verification
GEMINI_API_KEYis set or--api-keyis provided before any API call- Output filename follows the
yyyy-mm-dd-hh-mm-ss-name.jpgconvention - For edits, the
--input-imagepath exists and is accessible - Final deliverables use
--resolution 4K; drafts use 1K
Sibling skills
gpt-imagen— same shape, different provider. Choose this skill (Gemini / Nano Banana) for multi-image composition, native 4K/extreme aspect ratios, or text-in-image rendering. Choosegpt-imagenwhen the user asks for DALL-E /gpt-image-1, needs precise inpainting/masking, or has only anOPENAI_API_KEY.