crapify 0.2.0

Deep-fry your images, and other crimes against pixels.
crapify-0.2.0 is not a library.

crapify

Deep-fry your images, and other crimes against pixels.

crapify is the evil twin of mogrify. Same CLI ergonomics as ImageMagick's batch image-transform tool, opposite goal: take a perfectly fine image and make it look like total dogshit. The crapification is pluggable — each transform is a named crapifier you can stack, parameterize, and chain into a pipeline.

What it does

The flagship crapifier is deep-fry, which reproduces the mid-2010s "this meme has been forwarded so many times it's become a hot mess" aesthetic. The recipe:

  1. Re-save the image as a low-quality JPEG several times in a row, so the compression damage compounds with every round-trip.
  2. Push saturation and contrast past where a sane image editor would let you go.
  3. Sharpen edges hard so the blocky JPEG patches grow visible halos around everything.
  4. Sprinkle grainy speckle on top so even the smooth areas look gritty.

Five preset doneness levels ship out of the box — raw, pan-seared, chicken-fried, deep-fried (the default), forwarded-by-your-dad — each one bundling all seven knobs (quality, passes, saturation, contrast, brightness, sharpen-radius, noise) into a single named ramp. Pass --preset <slug> to pick one; pass individual knobs to override.

The second crapifier is palettecrush: snap every pixel to a tiny fixed palette (web-safe 16, GameBoy green, CGA, NES, C64, Atari 2600 — twelve catalogs ship in the box) with optional dithering, for the "saved-from-a-1997-GeoCities-page" look. Three named presets — geocities (16-color CSS palette + 8×8 Bayer crosshatch, the default), gameboy-pocket (4 swamp greens, no dither), cga-eyestrain (CGA cyan/magenta, no dither). Adaptive quantization via --colors N is the escape hatch when you want a custom-tuned palette.

Other crapifiers are sketched (xerox-machine simulation, format-rotting through pointless conversions, aspect-ratio mangling), but v0.1.0 shipped deep-fry and palettecrush landed in the next release.

Try it

# Default ("deep-fried") preset:
crapify deep-fry in.png out.png

# Maximum doneness:
crapify deep-fry --preset forwarded-by-your-dad in.png out.png

# Preset + targeted override:
crapify deep-fry --preset deep-fried --saturation 2.0 in.jpg out.png

# Raw knobs, no preset:
crapify deep-fry --quality 32 --passes 5 in.png out.png

# Palette-quantize to the geocities preset (web-safe 16 + bayer-8):
crapify palettecrush in.png out.png

# Pick a different palette + dither:
crapify palettecrush --palette nes-54 --dither floyd-steinberg in.png out.png

# Adaptive 4-color palette, no dither:
crapify palettecrush --colors 4 --dither none in.png out.png

# Pipeline: deep-fry first, then palettecrush:
crapify deep-fry --preset chicken-fried + palettecrush --preset geocities in.png out.png

Doneness presets

crapify deep-fry --help ends with this preset table. Each row is a complete recipe — pick a doneness level and you get all seven knobs at once. Override individual knobs alongside --preset to mix-and-match.

PRESETS (via --preset <slug>):
  raw                    "Raw"                    q=95, 1 pass.  Barely touched.
  pan-seared             "Pan seared"             q=78, 1 pass.  Light crunch.
  chicken-fried          "Chicken fried"          q=60, 2 passes. Visible JPEG mess.
  deep-fried             "Deep fried"             q=50, 3 passes. The canonical look (also the default).
  forwarded-by-your-dad  "Forwarded by your dad"  q=32, 5 passes. Maximum doneness.

Full per-knob docs with units and value ranges:

crapify --help               # top-level: pipeline grammar + registered stages
crapify deep-fry --help      # per-stage: every knob + the preset table
crapify palettecrush --help  # palette catalog + dither options + preset bindings

Pipeline grammar

Stages are composed in a single command, separated by +. The last two positional arguments are always input and output:

crapify <stage> [args] + <stage> [args] ... <input> <output>

Each crapifier between +s gets its own argument parser, so flag names don't collide across stages. v0.1.0 shipped deep-fry alone; subsequent releases add more crapifiers (starting with palettecrush) that drop straight into the pipeline. Reproducible-randomness (a global --seed) is deferred to a later release; for now, deep-fry's grain pattern is fresh per invocation. palettecrush is fully deterministic — same input + same flags = identical output every time, no seed needed.

Install

cargo install crapify

Or grab a pre-built binary from the latest release (Linux x86_64, macOS Apple Silicon, Windows x86_64).

Or build from source:

git clone https://github.com/bojanrajkovic/crapify.git
cd crapify
cargo build --release
./target/release/crapify --help

Requires Rust 1.95 or later; the pinned toolchain lives in mise.toml.

Why does this exist?

The deep-fried-meme aesthetic was a defining visual of mid-2010s internet culture, and there's no good CLI tool for reproducing it. ImageMagick can do it in four lines of shell, but the bit is having a dedicated, lovingly-named binary. A small Rust CLI is also a fine shape for hands-on time with the image and imageproc crates. And if anyone needs a practical excuse: thumbnailers, OCR, and vision models all have to survive degraded inputs in the wild, and crapify is a convenient fuzz/torture input generator. Mostly, though, it's funny, which is enough.

License

WTFPL. See LICENSE.