crapify 0.4.0

Deep-fry your images, and other crimes against pixels.
crapify-0.4.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.

The third crapifier is xerox: run the image through a photocopier a few times — per-pass blur, compounding contrast, toner-speckle noise, optional whole-image skew, optional paper-feed jitter, and an optional 1-bit threshold for the fax-machine look. Three named presets — decent-copy (1 pass, light), staff-meeting-handout (3 passes, jittery, the default), from-a-fax-from-1994 (8 passes, binarized, tilted).

The fourth crapifier is webcam-1999: nearest-neighbor downscale to a low internal resolution, oversharpen the small buffer, then nearest-neighbor upscale back so the sharpen halos blow up into block-scale stripes around every chunky pixel boundary. Plus a CCD-style saturation/tint pair and the occasional dropped scanline for that comb-tooth horizontal tear. Three named presets — quickcam-vc (640×480, slight warm cast), aim-buddy (320×240, cool cyan cast, the default), parents-bought-the-cheap-one (160×120, washed colors, visible tears). Aspect-mangle to fixed 4:3 is intentional by default (same as a real fixed-sensor webcam); pass --preserve-aspect to keep your input's ratio.

Other crapifiers are sketched (format-rotting through pointless conversions, aspect-ratio mangling), but deep-fry, palettecrush, xerox, and now webcam-1999 ship today.

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

# A photocopy of a photocopy (default = staff-meeting-handout):
crapify xerox in.png out.png

# Fax from 1994 — 8 passes, 1-bit, skewed:
crapify xerox --preset from-a-fax-from-1994 in.png out.png

# The canonical 1999-webcam look (320×240 nearest upscale, cool CCD cast):
crapify webcam-1999 in.png out.png

# Top of the era's lineup — 640×480, mild oversharpen:
crapify webcam-1999 --preset quickcam-vc in.png out.png

# Keep the input's aspect ratio instead of squishing to 4:3:
crapify webcam-1999 --preserve-aspect in.png out.png

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

# Full chain: webcam-1999, deep-fry, palettecrush — every aesthetic crime at once:
crapify webcam-1999 + 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
crapify xerox --help         # passes/blur/contrast/noise/skew/jitter/threshold + presets
crapify webcam-1999 --help   # downsample/sharpen/saturation/tint/scanlines + presets

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.