A browser tool that loads an image and re-encodes it as a lossy JPEG repeatedly,
so that generational compression loss accumulates in the pixels. Each pass calls
canvas.toDataURL('image/jpeg', quality), loads the result back into the canvas,
and encodes again, so every generation passes through the browser’s own JPEG
codec. Defaults are 50 iterations at quality
0.30, adjustable to 200 iterations and any quality from 0 to 1.
Three optional passes can run between re-encodes, in fixed order: per-pixel noise built from a shared luminance term plus a smaller per-channel term, a color shift pushing red up and blue down with a slight contrast adjustment, and a five-point sharpening convolution over each pixel and its four neighbors. All three are hand-written loops over the pixel array, and all default to off. The interface yields to the event loop each iteration so progress can render. Saving exports at quality 1.0, keeping the final generation intact.
The whole application is one HTML file with inline CSS and JavaScript, and images stay in the browser. The interface is styled as a Windows 95 dialog and closes with a passage from Hito Steyerl’s “In Defense of the Poor Image.”