# ComfyUI — Pixel Snapper Turn any image into clean, grid-aligned **pixel art** inside ComfyUI, using the compiled [SpriteFusion Pixel Snapper](https://github.com/Hugo-Dz/spritefusion-pixel-snapper) engine — plus color controls, classic video-game palettes, a pixel-perfect resizer, and an interactive preview with a magnifier. ![Workflow preview](docs/workflow.png) > _Example workflow: Load Image → Pixel Snapper (Engine) → Pixel Art Preview → > Pixel Art Resizer → Preview Image, with a Video Game Palette node._ --- ## ✨ Features - **Real snapping engine** — detects the native pixel grid and downscales via majority-color voting (not a naive resize). - **Color controls** — saturation / contrast / brightness applied *before* the snap. - **21 video-game palettes** — Game Boy, NES, PICO-8, C64, ZX Spectrum, DawnBringer, and more, in a dedicated node. - **Aspect-ratio fix** — corrects the engine's occasional "flattening" so output keeps the source proportions. - **Pixel Art Resizer** — scale up crisp (nearest) or shrink down to pixel-art resolution. - **Pixel Art Preview** — crisp nearest-neighbor rendering with an interactive **magnifier lens** that follows your cursor. --- ## 🧩 Nodes All nodes live under **Add Node → image → pixel_art**. ### Pixel Snapper (Engine) Runs the compiled engine, then layers optional color and palette processing around it. | Input | Description | |-------|-------------| | `image` | Input image | | `colors_k` | Number of output colors (ignored when a palette is connected) | | `saturation` / `contrast` / `brightness` | Color tweaks applied **before** the snap (they influence the engine's k-means) | | `fix_aspect` | Corrects the engine's aspect-ratio flattening (trims the over-represented axis, nearest). On by default | | `keep_output_size` | Upscales the result back to the original size (nearest) | | `palette` *(optional)* | A fixed palette from the **Video Game Palette** node | | `palette_dither` *(optional)* | Floyd–Steinberg dithering during palette remap | ### Video Game Palette Dropdown of classic palettes → outputs a `GAME_PALETTE`. Connect it to the Pixel Snapper's `palette` input. When connected, the engine's `k` becomes the palette size and the output is remapped to the **exact** palette colors. ### Pixel Art Resizer Resizes pixel art without blurring. | Input | Description | |-------|-------------| | `mode` | `scale_factor` (multiply) or `target_size` (width/height) | | `scale_factor` | Factor in `scale_factor` mode (e.g. `4.0` = 4×) | | `width` / `height` | Target size in `target_size` mode | | `interpolation` | `nearest` (crisp upscale), or `box`/`lanczos`/`bicubic`/`bilinear`/`hamming` (downscale) | | `keep_aspect` | Preserve aspect ratio in `target_size` mode | > **Tip:** use `nearest` to enlarge pixel art; use `box` to shrink a large image > down to a pixel-art resolution. ### Pixel Art Preview *(output node)* Displays the image with crisp (nearest-neighbor) rendering and an interactive magnifier — hover the image to zoom in on individual pixels. | Input | Description | |-------|-------------| | `magnifier` | Toggle the lens on/off | | `zoom` | Magnification (2–32×) | | `lens_size` | Lens diameter in pixels | --- ## ⚙️ How it works 1. **Grid detection** — the engine analyzes intensity peaks to estimate the pixel step size on each axis, then an edge-following "walker" places grid cuts. 2. **Downscale** — each grid cell is collapsed to its most frequent color (majority voting), producing a small, crisp pixel-art image. 3. **Color quantization** — colors are reduced to `k` via k-means (or to a fixed palette when one is connected). 4. **Wrapper layer (this repo)** — the ComfyUI nodes handle image ↔ tensor conversion, pre-snap color adjustments, the `fix_aspect` correction, palette remapping, resizing, and the crisp magnifier preview (a small front-end widget in `web/pixelart_preview.js`). The engine runs as a bundled `.exe` invoked per image: ``` spritefusion-pixel-snapper.exe ``` --- ## 📦 Installation 1. Copy the `comfyui_pixel_snapper` folder into `ComfyUI/custom_nodes/`. The `spritefusion-pixel-snapper.exe` binary is **included**, so it works standalone on any Windows machine — no path setup required. 2. *(Optional)* To use your own build of the engine, simply replace `spritefusion-pixel-snapper.exe` in the node folder with your binary (same name). 3. Restart ComfyUI, then hard-refresh the browser (**Ctrl+F5**) so the preview widget's JavaScript loads. Dependencies (`torch`, `numpy`, `Pillow`) ship with ComfyUI. > ⚠️ **Windows only** — the engine is shipped as a `.exe`. On Linux/macOS you would > need to build the engine from source (see credits). ### 🔒 Binary safety The bundled `spritefusion-pixel-snapper.exe` is the compiled [open-source engine](https://github.com/Hugo-Dz/spritefusion-pixel-snapper). You can verify it yourself on VirusTotal: **[VirusTotal scan report](https://www.virustotal.com/gui/file-analysis/MGE0Zjk1MjU5M2Y3ZGNlNDRlZWEwNDQ4OTk5YjZiZjA6MTc4MzM2NDE0Ng==)** Prefer full trust? Build the engine from source (see credits) and replace the `spritefusion-pixel-snapper.exe` in the node folder with your own binary. --- ## 🎨 Included palettes (21) Game Boy (DMG / Pocket) · NES (Full 54) · PICO-8 · CGA (Palette 1 / EGA 16) · Sweetie 16 · DawnBringer 16 · DawnBringer 32 · Commodore 64 · ZX Spectrum · Endesga 32 · Resurrect 64 · SLSO8 · Oil 6 · 1-Bit Monitor Glow · 2-Bit Demichrome · Ice Cream GB · Kirokaze Gameboy · Rustic GB · Mist GB --- ## 🙏 Credits - **Pixel-snapping engine** — [SpriteFusion Pixel Snapper](https://github.com/Hugo-Dz/spritefusion-pixel-snapper) by **Hugo Duprez**. All credit for the core snapping algorithm and the compiled binary goes to the original author; please refer to the upstream repository for its license and terms. - **ComfyUI custom node & integration** — implemented by **[HexaDucket](https://github.com/HexaDucket)**. The nodes, palettes, aspect-ratio fix, resizer, and the magnifier preview widget in this repository are my own work wrapping the engine for ComfyUI. ---