The editor edits a document, not your photograph

Nothing you drag is ever applied to the preview you are looking at — it is recorded, and replayed against the full-size original.

5 min read

What the canvas is actually building

While you work, the editor is not modifying an image. It is assembling a description: which filters are on and how far, where each piece of text sits, which stickers you placed, what colour the frame is. The picture on screen is that description drawn over a small copy of your photograph, refreshed as you change it.

When you export, the description is sent and re-drawn against the original file at its real size. A caption you nudged onto a nine-hundred-pixel preview is rendered onto six thousand pixels of photograph, and it lands in the same place — not approximately, but by construction.

The reason it can is that nothing in the description is measured in pixels. Every position, size and radius is a percentage of the base image, so there is no scale factor for either side to apply, round differently, or forget.

Filters defined once, run twice

Brightness, contrast, saturation, hue, greyscale, sepia, vintage and invert all reduce to the same thing: a three-by-three matrix applied to the colour channels, plus a per-channel offset. That matrix is computed by one shared piece of code.

The browser hands it to an SVG colour-matrix filter to draw the preview. The server runs the identical numbers over the actual pixel data. Neither side decides anything on its own, so neither can quietly drift from the other — which is the failure mode this arrangement exists to remove.

The matrices are the ones the Filter Effects specification defines for the CSS functions of the same names, so a saturation of 1.4 here means precisely what it means anywhere else on the web.

Blur and sharpen are convolutions rather than per-pixel arithmetic, so they stay separate and run after the matrix in a fixed order. Blur is expressed as a percentage of the image width for the same reason as everything else: a two-pixel blur on a preview has to become a thirteen-pixel blur on the original, or the export is not the thing you approved.

Stickers, frames and text

The built-in stickers are path data authored in a hundred-by-hundred box, defined in shared code and drawn from the same definition on both sides. They are shapes rather than small pictures, so placing one on a very large photograph keeps it crisp instead of enlarging a bitmap.

A sticker you upload yourself is re-encoded on the way in and scaled down to the size the layer actually uses. That is what makes it safe to embed in the render — whatever the file was, what reaches the renderer is pixels this server produced — and it stops a twenty-megapixel upload becoming tens of megabytes of encoded text inside the drawing instructions.

Text is not wrapped for you. A line break is one you typed. Automatic wrapping would have to be decided from font measurements, and the browser's measurements are not the server's — so the breaks would differ between what you saw and what you got, which is the one thing this tool refuses to allow.

Fonts
A sans, a serif and a monospace, named identically on both sides.
Hidden layers
Stay in the document, so unhiding restores them exactly.
Output
PNG, or JPEG flattened onto white since JPEG carries no transparency.

One image at a time

The editor takes a single file of up to twenty-five megabytes, and a smaller number of tasks per day than the simpler tools. It runs a full re-render of a large photograph rather than a single pass of an encoder, and pretending otherwise by allowing batches would only mean queueing behind yourself.

It accepts JPEG, PNG and WebP. The document you build is saved by your own browser as you work, so a refresh offers to put the arrangement back rather than starting you over. The photograph itself is not saved anywhere local — it follows the same expiry as every other upload here.

Frequently asked questions

Will the export look exactly like the preview?
That is the design goal and the reason for the architecture above. Filters share one definition, layers are positioned proportionally, and the stickers are the same path data in both. The visible difference is resolution: the export has all of it.
Can I undo after exporting?
Your document is still there, so you can adjust and export again. Each export is a fresh render of the original file, not an edit stacked on the last result, so exporting five times does not degrade anything.
Why is my exported JPEG missing the transparency?
JPEG has no alpha channel, so anything the layers left clear is filled with white on the way out. Choose PNG if the transparency is part of what you are making.