How room repaints work on Swatcher
As of today, any Swatcher account can upload a photo of its own room and see the walls repainted in a real paint from the catalogue. Free accounts get 3 repaints, Pro gets 30 a month, and each one costs me about 4 cent.
The room visualiser I built earlier uses stock rooms rendered in Blender and recolours them in the browser with plain colour maths. I’d ruled out generative models for it: they guess, and a paint tool that guesses is a bad paint tool. But I think people kept want their room, not mine. So I built repaints as an experiment, and spent most of the effort on the parts around the model: pinning it to a real paint, measuring how far it drifts, and never charging for a miss.
What you do
- Upload a photo of the room.
- Pick a wall colour from the catalogue or your favourites. Optionally pick a second paint for the trim: skirting, doors etc…
- Wait a bit while the repaint runs in the background.
- Drag a before/after slider across the result.
- Try more colours on the same photo.
If a repaint fails, nothing is charged and you get a short reason: the model declined the photo, the service was busy, or it just didn’t work.
Under the hood
It’s a Laravel app, so a repaint is a queued job wrapped around one image-model call to OpenAI through the Laravel AI SDK. Four parts do the real work.
1. Crop before you store
The image model only returns three shapes: square, 3:2 and 2:3. On upload I resize the photo, strip its metadata (including EXIF location), and centre-crop it to whichever of those shapes is nearest. It’s cropped before it’s saved, so the original I keep and the picture the model returns are exactly the same shape. That’s what lets the slider line them up, and the colour check compare them pixel for pixel.
2. Tell the model exactly what may change
Left alone, an image model “improves” the whole picture. It brightens the window, tidies the sofa, nudges the camera. So the prompt is deliberately bossy. It names the paint by name, brand and exact hex, for example “Studio Green” by Farrow & Ball, exact colour #464d4b, and asks for that hex as it would be lit in this photo, not a similar shade.
Then it lists what must not change: lighting, shadows, reflections, wall texture, furniture, floor, ceiling, windows, artwork, people, perspective, framing. With no trim paint chosen, the trim is on that list too.
3. Measure how close it got
A model asked for #464d4b won’t always paint #464d4b. I don’t want to hide that, so every result is measured.
- Shrink the original and the result to the same small grid, 96 pixels wide.
- Convert every pixel to CIELAB, a colour space built so that distances roughly match what eyes see.
- Keep the pixels that changed a lot between before and after. Those are what the model repainted.
- Drop changed pixels whose hue is more than 45 degrees from the paint’s hue. That stops a recoloured cushion or a repainted skirting board skewing the reading. For near-greys, where hue means little, this step is skipped.
- Take the median of what’s left as “the wall colour”, and work out its CIEDE2000 distance (delta E) from the paint.
Under about 3, most people can’t tell two colours apart, and the page says the wall came out close to the paint. Up to 6, it says near. Past that, it says nothing rather than make a claim it can’t back up. Some gap is expected even from a perfect repaint, because a wall in shadow is genuinely darker than the chip.
4. Only charge for a picture
Credits are held while a repaint runs and spent only once a result is safely written to disk. A worker claims each repaint with a conditional update, so two workers can never run it twice. The charge happens under a lock on both the account and the repaint, because the model call can take minutes and the person might have deleted it in the meantime. A scheduled command fails anything stuck too long, and none of these paths can overwrite a repaint that already succeeded and was paid for.
What it can’t do (yet)
- It’s still a model. The prompt asks it to leave everything else alone, and mostly it does. Sometimes a lamp shifts or a shadow softens. The slider makes that easy to spot.
- The colour is close, not exact. The visualiser’s maths sets an exact hex on a known wall. Here the model picks the pixels and the shade, and I can only measure the result afterwards. A trim paint with a similar hue to the walls can also muddy the reading.
- There’s a ceiling on cost. At about 4 cent a colour, the risk is a sudden spike, not normal use. So there’s a global daily cap for free repaints and a separate, higher one for Pro, both enforced under a lock so two uploads can’t grab the last slot.
- Your photo goes to OpenAI. Only to make the repaint; the privacy policy says so. Delete a repaint and its photo goes once nothing else uses it. Delete your account and they all go.
The obvious next step is a hybrid: let the model find the walls, then let the visualiser’s colour maths set the exact paint. I’m holding off until I see how people actually use it.
Try it
Sign up at swatcher.ie, open the visualiser and choose “Your own room”. The first 3 repaints are free. If it gets a colour badly wrong, I’d love to see the photo and the paint you picked. Those cases are what will decide whether the hybrid gets built.