Editable ad layers without a layer model: composite PNGs in Pillow

Sume returns flat images, not layered files. Generate a background and transparent elements as separate calls, then stack them yourself with Pillow.

4 min readSume
All posts

If you want an ad as editable layers, generate each layer as its own image and stack them in your own code. Sume's Image API returns a flat image per result, not a layered file, so layers come from separate calls: a background, then elements requested with background: "transparent" on ChatGPT Image 2.5.

Layered output is a current open-weight topic: inclusionAI's Ming-Image-0.1-Design-Layer decomposes flat designs into editable layers with RGBA outputs (digitalapplied tracker, read 2026-10-02). Sume does not serve it; this post is the workaround.

Which call makes which layer?

Request the background with no subject and keep text out of it. Request each element on its own with background: "transparent". Sume's docs list background as auto, transparent, or opaque, supported by ChatGPT Image 2.5.

Layer plan, read 2026-10-02
LayerRequestKey field
BackgroundScene with an empty area for the productbackground: "opaque"
ProductSingle product on nothingbackground: "transparent"
BadgeSale badge, no textbackground: "transparent"
HeadlineNot generated: set it in codenone

How do I stack them in Pillow?

Download each result, open it as RGBA, and use alpha_composite at a position. Setting the headline in code with your own font keeps the copy exact and editable.

from PIL import Image

background = Image.open("background.png").convert("RGBA")
layers = [("product.png", (180, 260)), ("badge.png", (40, 40))]

for path, position in layers:
    layer = Image.open(path).convert("RGBA")
    low, high = layer.getchannel("A").getextrema()
    if low == 255:
        raise SystemExit(f"{path} has no transparency")
    background.alpha_composite(layer, position)

background.convert("RGB").save("ad.jpg", quality=92)

What are the limits?

Each layer is a separate paid generation, and layers do not share lighting, so match the light in the prompts. Transparent output needs a model that lists background; a request that sets a parameter the model does not list is rejected with 400 unsupported_parameter. Check the Image API docs for the current list, and read the alpha channel as above before you trust a PNG.

Sources

Related posts

More in Use cases

All Use cases posts

Written by Sume