150 lines
6.2 KiB
Markdown
150 lines
6.2 KiB
Markdown
# 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.
|
||
|
||

|
||
|
||
> _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 <input.png> <output.png> <k>
|
||
```
|
||
|
||
---
|
||
|
||
## 📦 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.
|
||
|
||
---
|
||
|
||
<!-- Optional: add a LICENSE file. Keep it compatible with the upstream engine's license. -->
|