Image Generation
A picture from a prompt, or an edit of pictures you supply. The OpenAI Images API in its GPT-image form, so an existing client points at Paddock and works.
Research and evaluation only. Qwen-Image 2.1 ships under the Qwen Research License, which does not permit commercial use. That is the model's licence rather than Paddock's, and it governs what you do with the pictures it makes.
Availability
Both endpoints need an image model loaded. Ask the server rather than probing:
curl -s localhost:11540/api/server | jq '{model: .image_model, gen: .image_generation}'
# {
# "model": "qwen-image-2.1",
# "gen": {
# "size_multiple": 32,
# "max_side": 2752,
# "default_size": "1024x1024",
# "default_steps": 40,
# "max_steps": 100,
# "max_n": 10,
# "edit": true,
# "max_references": 10,
# "stream": true,
# "max_partial_images": 3,
# "output_formats": ["png", "webp", "jpeg"]
# }
# }edit: false means the model is loaded without its vision tower: text-to-image is served, editing is not. Start the model with its mmproj file to enable edits.
A Picture From a Prompt
curl -X POST localhost:11540/v1/images/generations \
-H 'Content-Type: application/json' \
-d '{
"prompt": "A hand-painted shop sign reading OPEN LATE, weathered blue paint",
"size": "1024x1024",
"quality": "high"
}' | jq -r '.data[0].b64_json' | base64 -d > sign.pngImages come back as b64_json and nothing else, which is what the GPT image models do. response_format: "url" is refused by name rather than quietly ignored.
Request Fields
| Field | Default | Notes |
|---|---|---|
prompt | required | Up to 32,000 characters. Read by a full 8B language model, so long descriptions hold together. |
size | 1024x1024 | WIDTHxHEIGHT on the 32-pixel grid, up to 2752 a side, or auto. |
quality | high | A step count: low is 20 steps, medium 30, high 40. |
n | 1 | Up to 10 images from one seed, each a different draw. Must be 1 when streaming. |
seed | 42 | A plain request is reproducible because of this. |
background | - | transparent uses the model's own RGBA form. |
output_format | png | png, webp (keeps alpha) or jpeg (flattened). |
steps | from quality | A Paddock extra: an explicit step count up to 100, overriding quality. |
width / height | - | Paddock extras. Pass these or size, never both. |
A size off the 32-pixel grid is refused, not rounded. The pipeline would silently round 1000x1000 to 992x992 and you would never learn why the picture came back the wrong size, so the request fails instead with the reason.
Previews While It Renders
A 1024x1024 image at 40 steps takes roughly 40 seconds on an A6000, which is a long time to show a user nothing. Set stream: true and the render reports progress as Server-Sent Events:
curl -N -X POST localhost:11540/v1/images/generations \
-H 'Content-Type: application/json' \
-d '{"prompt": "a lighthouse in fog", "stream": true, "partial_images": 3}'You get up to three image_generation.partial_image events, then one image_generation.completed carrying the final image and the usage. Events are data-only and discriminated by type, which is what the OpenAI SDK's image stream type parses.
A preview is not a crop or a low-resolution pass: it is the engine's estimate of the finished picture, decoded part way through, so it is the image the render is converging on. Asking for previews without stream: true is refused, since there would be nowhere to send them.
Editing Pictures
The edit form is multipart, with one or more reference pictures and an instruction:
curl -X POST localhost:11540/v1/images/edits \
-F 'image=@kitchen.png' \
-F 'prompt=Make the cabinets dark green and add a window above the sink' \
-F 'quality=high' | jq -r '.data[0].b64_json' | base64 -d > edited.pngUp to ten references, sent as repeated image parts (image[] in the SDKs). The output takes the shape of the last reference unless size says otherwise.
There is no mask. This model edits from the instruction and the pictures, so mask is refused by name rather than accepted and ignored.
size moves the references with it. One resolution sizes both the references and the output, so a 512x512 render conditions on 512x512 references. That pairing is deliberate: conditioning a small render on full-size references produces a copy of the input with the instruction ignored.
What Is Refused
These fail with a 400 and a message saying why, rather than being silently dropped:
- The DALL-E fields:
style, andresponse_format: "url". quality: "standard"or"hd", which are DALL-E's names for it.nabove 1 while streaming.partial_imageswithoutstream: true.- A size off the 32-pixel grid, or both
sizeandwidth/height. maskon an edit.
Memory
The model is three downloads: the diffusion weights, the text encoder and the VAE. Full quality wants about 17 GB of VRAM and the compact build about 10 GB, plus working room that grows with the picture, roughly 6 GB more at 1024x1024. Editing needs the vision tower loaded alongside.
In the Studio a picture is a conversation: ask for one, then ask for changes, and each turn edits the last result. See Studio.