Replace a dull sky in a property photo: mask only the sky

Swap a grey sky for blue in a property photo: build a sky mask in Pillow and send a mask_url edit to gpt-image-2.5. $0.021 at medium, $2.10 for 100 photos.

5 min readSume
All posts

To replace a dull sky in a property photo, build a mask that covers only the sky, upload it, and send the photo with mask_url to openai/gpt-image-2.5, asking for a clear blue sky with a few soft clouds. On Sume a one-reference 1024x1024 edit is $0.021 at medium and $0.0835 at high, so 100 photos cost $2.10 or $8.35. Only ChatGPT Image 2.5 accepts mask_url among the Sume image models.

A sky edit looks simple but fails at the roofline, where trees, chimneys and aerials cut into the sky. The mask is the part that decides the quality.

Build the sky mask

For a rough start, a polygon above the roofline is often enough. For houses with trees, a colour threshold on the blue and grey values of the sky gives a tighter outline, with feathering at the edges. Draw the mask at the same size as the photo.

from PIL import Image, ImageDraw

src = Image.open("house.jpg")
w, h = src.size
mask = Image.new("L", src.size, 0)
ImageDraw.Draw(mask).polygon(
    [(0, 0), (w, 0), (w, int(h * 0.30)), (int(w * 0.55), int(h * 0.38)), (0, int(h * 0.34))],
    fill=255,
)
mask.save("sky_mask.png")
print("mask", mask.size)

Polarity and hosting

The Sume docs say mask_url is a public HTTPS mask URL and do not publish whether white or black marks the area to edit. Test one image at low and see which side changes, then lock that convention for the batch. Upload the mask somewhere public; Sume rejects localhost, private-network and non-HTTPS URLs before submission.

Keep aspect_ratio on auto so the output frame matches the photo.

Prompt and cost

Ask for the light to match: the sun direction and shadow softness in the original. A bright blue sky over a house with flat overcast shadows looks fake because the lighting disagrees. Either ask for a soft, light-cloud sky that keeps the existing mood, or accept that this is a stylised image.

Sume cost of sky replacement, 1024x1024, one input image, per openai/gpt-image-2.5 edit (read 2026-10-07)
QualityPer photo100 photos
low$0.009375$0.9375
medium$0.021$2.10
high$0.0835$8.35

Disclosure and checks

Check the roofline, aerials and branches for halos. Diff the result against the source outside the sky region; it should be unchanged. If the listing platform or your local rules require disclosure of edited property photos, keep the original and mark the edited version. A replacement sky is a presentation edit, and it should not hide anything about the property, such as a neighbouring building or a power line that the buyer would see in person.

A practical tip on the mask: expand it by a few pixels with a blur before saving, so the model has some room to blend at the horizon. Then check the join between the new sky and the roofline at full size. Thin edges such as antennas, wires and bare branches are the usual place where a halo shows, and they are hard to mask by hand, so decide up front whether those photos are worth the effort.

Keep the prompt plain: name the sky you want, the time of day and the direction of light, and tell the model to leave the building, trees, ground and cars exactly as they are.

Batching 100 photos

For a batch, wrap the mask building and the API call in one function and run it over a folder with a small worker pool. Use an idempotency key per photo so a retry after a timeout does not bill a second edit; the related post on retries explains the same-key, same-payload rule. A completed job is billed and a failed job is not, so log each job id and its status.

Send the first ten photos at medium and review them as a set. If the skies look consistent and the rooflines are clean, run the rest. If a handful have halos, rerun only those at high. That keeps the bill near the $2.10 mark for 100 photos plus a few $0.0835 reruns, rather than $8.35 for everything.

Photos with complex rooflines, such as many trees or scaffolding, are the ones to flag for manual handling. A model cannot fix a bad mask, and a bad mask is the usual cause of a bad result.

Sources

Related posts

More in Use cases

All Use cases posts

Written by Sume