Die-cut sticker outline from a transparent gpt-image-2.5 PNG in Pillow
Request background=transparent on Sume, then add a white die-cut border by growing the alpha channel with MaxFilter. Code, border width math, and print notes.

Ask openai/gpt-image-2.5 for background: "transparent" with output_format: "png", then grow the alpha channel with ImageFilter.MaxFilter to get a solid white border and composite the artwork on top. A MaxFilter size of 2k+1 expands the shape by k pixels on every side, so a size of 25 gives a 12 pixel border, about 1.2 percent of a 1024 pixel image.
Why this model for stickers
Of the Sume image models, only ChatGPT Image 2.5 and its Sunburst variant accept background in the catalog. Other models return 400 unsupported_parameter for it, so a transparent sticker source needs this model, or a cutout step on another model's output.
A die-cut sticker has an outline that follows the artwork. That is the border step here, and the shape it gives is what a cutter follows.
Grow the alpha and composite
Take the alpha channel, apply MaxFilter(size) (size must be odd), and fill that shape with white. Then paste the artwork over it using its own alpha. The filter is a square kernel, so corners grow slightly more than diagonals; for round borders blur and threshold after.
import os, io, requests
from PIL import Image
H = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"]}
def gen(**body):
r = requests.post("https://api.sume.com/v1/images", json=body, headers=H, timeout=60)
r.raise_for_status()
if r.status_code == 202:
raise SystemExit("queued, read /v1/jobs/{id}/result: " + r.text)
return r.json()
def fetch(u):
return Image.open(io.BytesIO(requests.get(u, timeout=60).content))
from PIL import ImageFilter
out = gen(model="openai/gpt-image-2.5", background="transparent", output_format="png",
prompt="Cute cartoon avocado with sunglasses, thick clean outline, sticker art")
art = fetch(out["data"][0]["url"]).convert("RGBA")
k = 12
pad = Image.new("RGBA", (art.width + 4 * k, art.height + 4 * k), (0, 0, 0, 0))
pad.paste(art, (2 * k, 2 * k))
alpha = pad.getchannel("A")
grown = alpha.filter(ImageFilter.MaxFilter(2 * k + 1))
grown = grown.filter(ImageFilter.GaussianBlur(2)).point(lambda v: 255 if v > 100 else 0)
base = Image.new("RGBA", pad.size, (255, 255, 255, 0))
base.putalpha(grown)
base.paste((255, 255, 255, 255), mask=grown)
Image.alpha_composite(base, pad).save("sticker.png")
print("border px", k, "cost", out["usage"]["cost"])Pick the border width
Ask your printer for the border width their cutter needs; a few millimeters is a common starting point. Convert millimeters to pixels with your print resolution.
| Border | Pixels at 300 dpi | MaxFilter size |
|---|---|---|
| 2 mm | 24 | 49 |
| 3 mm | 35 | 71 |
| 1 mm | 12 | 25 |
Gotchas
- The MaxFilter is slow on large images. Work at the final print size, not at 4K.
- Soft glows or shadows in the generated art carry faint alpha that the border will include. Ask for clean edges in the prompt.
- The border adds pixels to the canvas, so pad first as shown, or the border is clipped at the image edge.
- Keep the sticker as PNG with alpha, and send a separate cut path if your printer asks for one.
Related recipes
To compare a model's transparent output with a cutout from another model, read transparent PNG vs cutout. Do not re-save through JPEG between steps, see PNG between passes. A sticker set made of squares can reuse the circle-crop recipe.
Sources
Related posts
More in Media tools
- Dim a bright 9:16 clip before captions: video-filter dim at 0.45
Sume video-filter's dim op multiplies luma by an amount above 0 up to 1. A free check validates it, then one $0.02 job makes the clip easier to caption.
- Dim a bright product clip before captions: free check, then encode
Make white captions readable on a bright product clip: the free /v1/video-filter/check, then a dim op at the $0.02 encode rate, then Timeline.
- Discord soundboard clip from Sume music: 5.2 s, 512 kb, mp3 or ogg
Discord's soundboard accepts mp3 or ogg up to 512 kb and 5.2 s. Cut a Sume track with timeline audio split to mp3 and check the size; wav will not fit.
- Documentary underscore with AI music: a 3-minute brief and cost
How to brief an instrumental underscore for a 3-minute documentary with narration: one Lyria request, a ducked bed in Timeline, and the full audio cost.
Written by Sume