App Store screenshots reject alpha: flatten a Sume PNG first

App Store Connect screenshots cannot include alpha or transparency. A PNG with an alpha channel from an image API needs flattening; here is a Pillow check.

5 min readSume
All posts

Apple's screenshot specification says images cannot include alpha channels or transparencies, and accepts .jpeg, .jpg and .png with 1 to 10 screenshots per set. A PNG straight from an image API may carry an alpha channel even when nothing in it is transparent, so flatten it onto a solid color before upload.

What Apple lists for the 6.9-inch iPhone display

The page lists three accepted sizes for each orientation.

iPhone 6.9-inch screenshot sizes (read 2026-10-03)
OrientationAccepted sizes in pixels
Portrait1260 x 2736, 1290 x 2796, 1320 x 2868
Landscape2736 x 1260, 2796 x 1290, 2868 x 1320

Why alpha sneaks in

Image APIs that return PNG often write RGBA files. The Sume Image API accepts output_format of png, jpeg, webp or svg, so asking for jpeg avoids alpha entirely, and the docs mark background as a ChatGPT Image 2.5 option you do not need here. A background or marketing frame generated as PNG, or any cut-out you composited yourself, can still hold an alpha channel, so test the final file rather than trusting the source.

Flatten and verify

The script requests a 9:16-ish backdrop as JPEG, resizes to the 1290 x 2796 accepted portrait size, and refuses to save if the mode is not RGB. For a PNG you composited, replace the open step with Image.open(path) and paste onto a solid RGB canvas using the alpha as the mask.

import os, io, requests
from PIL import Image
r = requests.post(
    "https://api.sume.com/v1/images",
    headers={"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"},
    json={"model": "bytedance-seed/seedream-4.5", "aspect_ratio": "9:16", "prompt": "clean pastel gradient backdrop, no text", "output_format": "jpeg"},
    timeout=90,
)
r.raise_for_status()
if r.status_code != 200:
    raise SystemExit("202: read the finished job from /v1/jobs/{id}/result")
img = Image.open(io.BytesIO(requests.get(r.json()["data"][0]["url"], timeout=60).content))
if img.mode in ("RGBA", "LA", "P"):
    rgba = img.convert("RGBA")
    flat = Image.new("RGB", rgba.size, (255, 255, 255))
    flat.paste(rgba, mask=rgba.getchannel("A"))
    img = flat
img = img.convert("RGB").resize((1290, 2796), Image.LANCZOS)
assert img.mode == "RGB"
img.save("appstore-shot-bg.png", optimize=True)

A check you can run on every file

The cheapest guard is to open every file you are about to upload and assert on its mode and size. Mode RGB means three channels; RGBA, LA and palette images with transparency can all carry alpha. Check the pixel size against the accepted list from Apple's page, since a file that is one pixel off is rejected the same as one that is far off. Do the check after the last edit, not after generation, because every later composite or crop can reintroduce an alpha channel. Apple also says 1 to 10 screenshots per set, so a script that writes more than ten files for one device size is a bug worth catching before upload. Keep the unflattened source images in a separate folder, so a change of background color means re-running the flatten step rather than regenerating anything and paying for it again.

Aspect note

1290 x 2796 has a width-to-height ratio of 0.461, narrower than 9:16 (0.5625), so a plain resize squeezes the image horizontally by about 18%. Crop the generated image to the target ratio first if the content has faces or a device frame. The backdrop in this example has neither, so a resize is enough. Whatever the file, the real app capture should sit on top of it unmodified.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume