One product photo, five ad shapes: Flux 2 Pro $0.1875, Qwen $0.125

Five shapes (1:1, 4:5, 9:16, 16:9, 21:9) from one photo: $0.1875 on Flux 2 Pro, $0.125 on Qwen Image, $0.50 on Nano Banana 2.1. Seedream 5 Lite lacks 21:9.

5 min readSume
All posts

Five ad shapes from one product photo (1:1, 4:5, 9:16, 16:9 and 21:9) cost $0.1875 on Flux 2 Pro, $0.125 on Qwen Image and $0.50 on Nano Banana 2.1 on Sume, one call per shape. Seedream 5.0 Lite lists the first four shapes but not 21:9, so it covers four of the five for $0.175. The prices are the billed endpoint figures from origin/main, read 2026-10-08.

This is regeneration, not cropping. Each call asks the model to stage the product again for the new frame, so the composition, background and sometimes small label details change from shape to shape. Check each result against the original before it goes into an ad.

Cost by row

Each row below takes up to 10 reference images. The count is the number of the five shapes the row lists.

Five shapes from one photo on Sume (read 2026-10-08)
ModelPer imageShapes listed (of 5)Cost for 5
Qwen Image$0.0255$0.125
Flux 2 Pro$0.03755$0.1875
Seedream 5.0 Lite$0.043754 (no 21:9)$0.175 for 4
Nano Banana 2.1$0.105$0.50

The loop

Each call passes the same reference and names its own aspect_ratio. Leaving aspect_ratio off is not the same as auto, and a shape you want should be named. The script prints the status and moves on if a call does not return 200; a 202 means the job is still running and its result is fetched from the job.

import os, requests

PHOTO = "https://example.com/tin.jpg"
RATIOS = ["1:1", "4:5", "9:16", "16:9", "21:9"]
headers = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
total = 0.0
for ratio in RATIOS:
    body = {
        "model": "black-forest-labs/flux.2-pro",
        "prompt": "Same tin, same label, restaged for this frame shape",
        "input_references": [{"type": "image_url", "image_url": {"url": PHOTO}}],
        "aspect_ratio": ratio,
    }
    r = requests.post("https://api.sume.com/v1/images", json=body,
                      headers=headers, timeout=60)
    if r.status_code != 200:
        print(ratio, "status", r.status_code)
        continue
    out = r.json()
    total += out["usage"]["cost"]
    print(ratio, out["data"][0]["url"])
print(f"total ${total:.4f}")

Keeping the set consistent

Same wording across all five prompts, with only the framing instruction changing, gives the most similar set. Tall 9:16 and wide 21:9 frames are the shapes where the product is most likely to shrink or move, so say in the prompt where it sits and roughly how large.

A cheaper first pass on Qwen Image costs $0.125 for the set. If the results hold up for your product, you do not need the dearer row.

Run the five calls one after another while you are testing, then switch to a small number in parallel once the prompt is stable. Each call still waits up to 30 seconds before Sume hands back a job envelope, so a timeout of 60 seconds in the client is enough to see either outcome.

Keep the original photo URL public for the duration of the batch. Sume fetches reference URLs from the public internet and refuses localhost, private-network and non-HTTPS addresses before it submits the work.

Sources

Related posts

More in Use cases

All Use cases posts

Written by Sume