All work
In progress · early days

RideLens

Car edits, without the learning curve.

An iPhone photo editor made for cars. Proper light and colour tools, masks that already know where the car is, and posters and stickers that sit behind it — because I kept seeing incredible car edits, and I can’t edit to save my life.

Role
Design & development, solo
Started
October 2026
Status
In progress, iPhone
Stack
Swift · SwiftUI · Core Image · Vision

01Why it exists

I kept saving other people’s car edits. I couldn’t make one of my own.

My feed is full of car photos that look like magazine covers. Mine looked like car photos. The people who make those edits use Lightroom — a subscription, and a tool built for people who already know what a “luminance range mask” is.

I don’t want a general editor. I want one that knows the car is the point: where it is, what colour it is, which part is the sky, where the plate is.

RideLens grew out of the photo studio I built inside RideCheck, where every trip becomes a card for Stories. I split it into its own app so it could become a real editor, not a feature.

The first spark came much earlier, with a tiny Python filter app — the day I realised a photo is just numbers, and numbers are something I can change.

02Before / after

Same photo. Better light.

My own photos, before and after an edit in RideLens: the scene pulled down, the car brought forward with its reflections intact, and the plate covered on the phone. Drag to compare.

Before: a silver Porsche Cayman on a brick forecourt in flat afternoon light, trees and an office block behind
After: the same Cayman with the scene darkened around it, the body bright and glossy, and the plate covered
Before Stealth

My own photos, cropped to fit. In the edits, RideLens covered the Cayman’s plate itself; every other plate here is blurred by hand.

03Posters

The car comes forward. The type goes behind it.

Every poster is drawn in code, so it fills itself in: the car, the drive, the distance and top speed. Because the car is lifted onto its own layer, the headline can sit between the car and the background — the look the edits I admired all had.

‘Series’ poster: a silver Porsche Cayman at sunset under a red 718 outline and ‘Cayman ’17’ script
‘Issue’ poster: a magazine cover titled RIDELENS with the Cayman and drive stats
‘Rally’ poster: the Cayman at night beside a glowing green dragon sculpture
‘Wanted’ poster: a BMW 3 Series with glowing angel-eye headlights, collaged in strips
‘Night’ poster: huge distressed 718 numerals over the Cayman at night, the dragon glowing white behind it
‘Gothic’ poster: blackletter ‘Cayman’ over the car in evening light
‘Race’ poster: the Cayman’s rear light bar glowing red under race-weekend type
‘Wildstyle’ poster: graffiti Porsche lettering and a blue paint stroke behind the car
‘Timeless’ poster: a torn-paper collage of the BMW in a car park
‘Touge’ poster: the Cayman with a sharp diagonal crop and big stats along the bottom
‘Speed Cam’ poster: the BMW from above framed like a speed-camera capture with red readouts
‘Outline’ poster: BMW 320I in outlined type behind the silver BMW, shot through the leaves
‘Catalog’ poster: a clean product-sheet layout of the Cayman with detail crops
‘Livery’ poster: yellow and pink race-livery type over the Cayman’s taillights
‘Arcade’ poster: neon arcade-game styling around the Cayman and the dragon
‘Legend’ poster: a ‘3 Series’ script over a big 320i, the BMW’s angel eyes glowing in a dark car park

Sixteen of the thirty poster styles. Real exports from the app, made from my own photos; plates are hidden by RideLens itself.

04Stickers & Reels

The drive, on top of the photo.

Stickers turn a drive into graphics — a lap time, a speedometer, a boarding pass from Jakarta to Jakarta. And any edit can leave as a vertical Reel that reveals itself from the original.

Lap sticker: a big 1:12:00 lap time over the Cayman Speedo sticker: a speedometer reading 132 over the Cayman at night Pass sticker: a boarding pass for a drive from JKT to JKT beside the BMW Cover sticker: distance, duration and top speed over a big PORSCHE headline
A “Reveal” Reel: 1080 × 1920 video, exported straight from the app.

05The editor

Fourteen tools, all thinking about the car.

Light and colour

Exposure, contrast, highlights and shadows, a tone curve, an 8-band HSL mixer, colour-grading wheels, black and white — and an Auto that exposes for the car.

Masks that know the car

Car, background and sky, plus linear, radial, brush and colour or luminance ranges. One-tap moves like “Pop the car” and “Moody sky”, and Paint to rewrap the body.

Motion

A rolling-shot blur behind the car only, in the direction you choose, and Wheel Spin that finds the wheels and spins them — brake calipers held still.

Plates and clean-up

Plates are found on the device and covered with a blank in the plate’s own colour, your own lettering, or pixels. Remove, Heal and Clone tidy the rest.

Posters and stickers

Thirty poster styles and fifteen sticker formats, drawn in code with the car’s details, the drive’s stats and maker badges.

Out the door

JPEG, HEIC or PNG up to full resolution, Instagram Story and Post sizes, a 2–5 slide carousel, and a vertical Reel video.

06How it’s built

Apple’s frameworks, no dependencies.

Pure Swift and SwiftUI on Core Image and Vision. No third-party packages, and no Metal on purpose — custom kernels would need the Metal toolchain at build time.

PipelineA non-destructive Core Image develop chain — white balance, exposure, dehaze, shadows and highlights — then one colour cube for everything per-pixel.
CarVision lifts the car out as its own layer; plates are found with on-device text and rectangle detection.
EditsOne value type holds the whole edit, so undo is a stack of values and copy-paste works by group.
ExportFull resolution in blocks and half-float stages, retried smaller if memory runs out. Reels are H.264 at 1080 × 1920.
PhotoStudioProcessor+Develop.swift
if d.temperature != 0 || d.tint != 0 {
    image = whiteBalanced(image, temperature: d.temperature, tint: d.tint)
}
if d.exposure != 0 {
    image = image.applyingFilter("CIExposureAdjust", parameters: [kCIInputEVKey: d.exposure])
}
if d.dehaze != 0 {
    image = dehazed(image, amount: d.dehaze / 100)
}
if d.shadows != 0 || d.highlights < 0 {
    image = shadowsAndHighlights(image, shadows: d.shadows / 100, highlights: min(0, d.highlights / 100))
}
let global = DevelopLUT.Global(d)
if !global.isIdentity {
    image = cubed(image, DevelopLUT.cube(for: global))
}

07Build notes

Making it feel like a real editor.

01

The car as its own layer

Vision’s foreground mask is cleaned up — shrunk a pixel, then softened — and the develop chain renders once. Both layers are cut from that single render, which is how a poster can slide between the background and the car without the two drifting apart in colour.

02

One colour cube for every slider

Contrast, curves, the HSL mixer, grading and black and white are baked into one 33³ lookup table, built across all cores. The maths happens in Oklab, and out-of-gamut colours are pulled in by reducing chroma rather than clipping channels, so hues don’t shift. Recent cubes are cached, so dragging one slider rebuilds only one.

03

Previews that never queue up

The whole edit is one comparable value, and undo is just a stack of them, with each drag grouped into a single step. Rendering is latest-wins: while a render is running, new changes only mark it stale, so a fast slider never builds a backlog.

04

Classic computer vision, not a model

Remove uses PatchMatch, coarse to fine. The wheel finder votes for circles, fits an ellipse and re-checks it up close — and declines when it isn’t sure. Wheel Spin then blurs each wheel in its own polar space. All of it runs on the phone.

Honest status

RideLens is days old, iPhone-only and English-only, and not on the App Store yet. Removal is patch-based, so busy backgrounds can come out looking collaged. Next on the list: sky and background replacement, wet-road reflections, and connecting it back to RideCheck.