ROT (2026)

(iterative JPEG recompression)
Doc. ref: HK-ROT-2026
Category
Tools & Infrastructure
Medium
single HTML file, vanilla JS, Canvas API
Venue
gitlab.com/closestfriend/rot
State
complete
Tags
image, compression, browser

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 — real recompression through the browser’s own JPEG codec rather than a filter imitating the look of it. Defaults are 50 iterations at quality 0.30, adjustable to 200 iterations and any quality from 0 to 1.

Each pass re-encodes the canvas as JPEG and draws the result back over itself; the pixel passes run between encodes when enabled.
Each pass re-encodes the canvas as JPEG and draws the result back over itself; the pixel passes run between encodes when enabled.

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 re-exports at quality 1.0, since the artifacts are already in the pixels by then.

The whole application is one HTML file with inline CSS and JavaScript. There is no framework and no network call. The interface is styled as a Windows 95 dialog and closes with a passage from Hito Steyerl’s “In Defense of the Poor Image.”

Last updated: 2026.09.03 20:20:09 UTCHnshokrian@gmail.com