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.

5 min readSume
All posts

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.

White bands in a 1600 px square, arithmetic read 2026-10-05
Source ratioFitted sizeBand each side
4:51280 x 1600160 px left and right
3:41200 x 1600200 px left and right
16:91600 x 900350 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.LANCZOS when 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

All Use cases posts

Written by Sume