Filter a picture
Photographic visual for How It Works

How It Works

How the lab works

One engine, one order of operations, and no server. Everything you see on the strip, the preview, the saved file and a batch is the same code running on a different-sized copy of your photo.

One engine for every frame

The filmstrip’s small frames, the draft that keeps up with a dragging slider, the preview, the full-size export and every photo in a batch are all the same call: run this effect with these settings and this finish on this picture. Only the picture differs — a 220-pixel thumbnail, a 560-pixel draft, a preview up to 1,600 pixels, or the photo at its own size. There is no fast approximation for the screen and a careful version for the file.

The order of operations

1. Decode
The file is read in the tab, turned the right way up, and a preview copy is made.
2. Look or rebuild
The chosen effect runs on the picture.
3. Strength
The result is mixed with the photograph — per pixel, through the Apply-to shape when one is set. Protect skin then gives skin back its own colour.
4. Tone
Exposure, contrast, highlights, shadows, saturation, warmth, tint, fade, the tone curve, then clarity.
5. Texture
Grain, bloom and halation, then the vignette and light leak.
6. Fit
The export frame is cut and resized, if one is chosen.
7. Encode
PNG, JPG, WebP, SVG or text, written in the tab. No location or camera data is copied in.

The order never changes by page: every route opens the same lab in a different mode.

Why the file matches the screen

Nothing in a recipe is a pixel count that would mean something different on a bigger picture. Grain cells scale with the long edge; bloom, glow, clarity and the light leak are computed on a reduced copy at a fixed working size and sampled back up; vignettes and masks are fractions of the frame; halftone cells, dither pre-scale, mosaic tiles and blur radii are multiplied by the ratio between the export and the preview. A dither palette cut from the photo is cut once, from the preview, and handed to the export.

The site’s build renders every effect on a preview and on a picture four times larger, averages both down, and fails if they differ by more than a few levels out of 255. Strength 0 is checked to return the photograph byte for byte.

What is stored, and what is seen

This browser keeps your favourite looks and saved recipes — names and numbers, never pictures, file names or sizes — in local storage. Settings strings are text you copy yourself. Nothing else is stored, and the photo is gone when you close the tab. On the live domain, Cloudflare Web Analytics counts page views without cookies; it cannot see the photo, because the photo never leaves the tab.

Questions

Is my photo sent to a server?
No. The photo is decoded in the browser tab, filtered by code running in the tab (in a Web Worker where the browser has one), and the file is encoded and saved in the tab. The page has no upload endpoint to send it to.
Why does the saved file match the preview?
Because they are the same code with the same settings. Only the size of the picture differs, and every length — a halftone cell, a glow radius, a vignette — is a fraction of the picture or is scaled by the ratio between preview and export. The site's build checks this numerically for every effect.
What does the site store?
Favourites and saved recipes, in this browser's local storage, as names and numbers. Never the picture, its file name or its dimensions.
What do the analytics see?
On the live site, Cloudflare Web Analytics counts page views without cookies. It does not see your photos — they never leave the tab. The privacy page has the details.

Back to the lab

Rendered on your computer, not on a server.