Pad an AI image to a white square for listings with ImageOps.pad
Marketplaces want square product images. Use ImageOps.pad on a Sume 4:5 or 3:2 image to add white bars without cropping the product, then save a JPEG.

Call ImageOps.pad(img, (1600, 1600), color="white"). It scales the image to fit inside the square, keeps its ratio, and fills the leftover bands with white, so nothing is cropped. A 4:5 image at 1600 pixels square becomes 1280 by 1600 with a 160 pixel white band on the left and the right.
Crop versus pad
A square listing slot forces a choice. Cropping with ImageOps.fit keeps the picture full but removes edges, which can cut a handle, a sleeve, or a shadow. Padding keeps every pixel and adds blank space.
For marketplace and catalog images, padding on white is the safer default, since the product is the point and a cut-off product is a rejection reason. For social feeds, a crop usually looks better.
The call
pad takes the image, a target size, a resampling method, a color, and a centering pair. Centering (0.5, 0.5) puts the image in the middle. A value of (0.5, 1.0) sits the product on the bottom edge, which can suit items on a floor.
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 ImageOps
out = gen(model="google/nano-banana-2", aspect_ratio="4:5",
prompt="Brown leather backpack on a pure white seamless backdrop, product photo")
img = fetch(out["data"][0]["url"]).convert("RGB")
square = ImageOps.pad(img, (1600, 1600), Image.LANCZOS, color="white", centering=(0.5, 0.5))
square.save("listing_square.jpg", quality=92)
w = round(1600 * img.width / img.height) if img.height >= img.width else 1600
print(img.size, "->", square.size, "image width inside", w, "cost", out["usage"]["cost"])Band size by source ratio
The bands follow from the ratio. At 1600 pixels square, these are the white areas you add.
| Source ratio | Fitted size | Band each side |
|---|---|---|
| 4:5 | 1280 x 1600 | 160 px left and right |
| 3:4 | 1200 x 1600 | 200 px left and right |
| 16:9 | 1600 x 900 | 350 px top and bottom |
Make the white match
- Ask the model for a pure white backdrop. A cream or gray backdrop next to pure white bands shows as a visible box.
- Check the corner pixel of the image. If it is not 255 on each channel, either prompt again or flood the backdrop to white first.
- Keep the original aspect for web pages and use the square only where the form demands it.
- Use
Image.LANCZOSwhen shrinking and save quality 90 or more.
Related
For a feed crop instead of a pad, see the 4:5 feed image recipe. Derive other widths from one master with the srcset recipe, and keep a lossless master as in PNG between passes. Check each marketplace's current size and background rules before you set the target.
Sources
Related posts
More in Use cases
- Paper abstract to a 30 s explainer: Wan 3.0 scenes, claims as captions
Turn a research abstract into a 30 s Wan 3.0 explainer on Sume without invented results: the model draws the scene, you type every claim as a caption.
- Failed payment reminder video: 20-second AI avatar script and cost
A friendly failed-payment clip from a Sume avatar: script rules, no scare wording, the API request and the cost per account on standard, plus and max.
- Same-second thumbnail frames for every episode of a Shorts series
YouTube lets each Short in a series have a custom thumbnail. Pull one frame per episode at the same second with Sume video-frames so the set looks consistent.
- Performance Max: 15 vertical + 15 horizontal Omni clips, $56.40
Performance Max takes 15 videos per orientation and one vertical 10-60 s clip for Shorts. Thirty 10 s Omni 1080p clips cost $56.40 on Sume.
Written by Sume