# Codebase Knowledge Base ## Patterns & Conventions - Single-file Python project (`main.py`), Pillow + numpy for image processing - CLI interface: `python main.py ` - Platforms defined as tuples in `PLATFORMS` list: (name, width, height, cols, rows) - Pixel grid sizes are log-distributed via `pick_grid_sizes()` - Palette mapping uses numpy vectorized nearest-color matching ## Architecture - `pixelate()` — core pixel art function: downscale → optional palette → upscale with NEAREST - `apply_palette()` — maps every pixel to closest color in a palette array - `create_banner()` — composes grid of pixelated cells + generates GIF animation - `pick_grid_sizes()` — generates log-spaced pixelation levels, capped at `end_fraction` of cell size - Output: PNG (static grid banner) + GIF (animated progression) per platform ## Testing - No test framework yet - Manual testing: `python main.py samples/sample1.jpg previews/sample1` - Verify: check output files exist and are valid images ## Gotchas - Pillow `quantize()` fails when colors > actual unique pixels in image (caused bugs with 1x1, 2x2 grids) - `end_fraction` must be relative to cell size, not source image size, or high-res stages look like originals - GIF frames use full banner dimensions — can get large for substack (1500x300) - `.gitignore` uses `/banner_*.png` (root only) to avoid ignoring previews/ subdirectories ## Discoveries (2026-04-01) - Unsplash direct URLs work for sample images (free license, no auth needed) - 4 palettes implemented: original, gameboy (4 colors), nes (36 colors), sepia (12 colors) - Influencer seeding identified as top growth strategy - GIF animation is the #1 viral hook — auto-plays on Twitter/X - Font caching matters — draw_label was probing filesystem on every cell - Floyd-Steinberg dithering is pure Python (slow on large images) — consider Cython or Pillow's built-in quantize dither for perf - `create_banner` has 11 params now — next refactor should bundle into a config dataclass - Legacy positional args via parse_known_args silently swallows typos — acceptable trade-off for backwards compat