# PixelOE pixelizes images by expanding outlines before downscaling, and ships three backends

> PixelOE is a Python pixel art library that avoids neural networks entirely, expanding the outlines of key features before downscaling so that edges survive, with a torch pipeline, a Slang compute-shader backend that runs on CUDA, Vulkan, D3D12 or CPU, and a slow numpy and OpenCV path. It is published on PyPI and comes with ComfyUI nodes and a Gradio demo.

**KohakuBlueleaf/PixelOE** — Detail-Oriented Pixelization based on Contrast-Aware Outline Expansion.

- Repository: https://github.com/KohakuBlueleaf/PixelOE
- Stars: 530 · Forks: 25
- Language: Python
- License: Apache-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/kohakublueleaf-pixeloe

## The method: widen the outlines, then downscale

PixelOE stands for Detail-Oriented Pixelization based on Contrast-Aware Outline Expansion, and the summary in the README is that it generates high-quality pixel art from standard images using a novel, contrast-aware approach. That approach focuses on preserving important visual details by first expanding outlines of key features, then applying an intelligent downscaling to the target resolution.

The ordering is the whole idea. A naive pixelization downsamples, and downsampling a high-contrast edge produces a thin, dim, half-pixel line that disappears at small sizes. Expanding the outline first gives the downsampler more pixels to work with, so the edge comes out solid rather than faint.

The features list spells out the components. No AI or NN required, using classical image processing methods for efficient and predictable results. Detail-oriented, emphasising preservation of fine details and sharp edges. Contrast-aware, adapting downsampling based on local image contrast. And outline expansion, broadening important features before downscaling to prevent loss of detail.

Two more feature entries are about control rather than about the algorithm. Flexible downscale modes offer various downsampling methods for different styles: center, contrast, k-centroid, bicubic and nearest. The mode is the single biggest lever on the output, because it decides how a pixel is chosen from the region it represents. Nearest picks one, center picks the middle, k-centroid picks a value near the cluster centre, bicubic interpolates, and contrast is the one that uses the local contrast information.

And colour palette optimization offers the option to quantize colour palettes for a classic pixel art aesthetic. That is a separate step from pixelization and it is the difference between a reduced-resolution photograph and something that reads as pixel art.

The promise in the README's own headline is to create stunning pixel art from high-resolution images without AI or complex networks, and the argument for that is predictability. A classical pipeline gives the same output for the same input every time, which is what you want in a render pipeline or a content pipeline where you need reproducibility.

## Three ways to call it, and they differ by more than speed

The Python API comes in three flavours, and the README is explicit that they are not equivalent.

The legacy path is numpy and OpenCV based and described as slow:

```python
import cv2
from pixeloe.pixelize import pixelize

img = cv2.imread("img/test.webp")
img = pixelize(img, target_size=256, patch_size=8)
cv2.imwrite("img/test2.webp", img)
```

The torch path is fast and GPU supported:

```python
import torch
from PIL import Image

from pixeloe.torch.pixelize import pixelize
from pixeloe.torch.utils import to_numpy, pre_resize

img = Image.open("img/snow-leopard.webp")
img = pre_resize(img, target_size=256, patch_size=4).cuda().half()
result = pixelize(img, pixel_size=4, thickness=3)
result_img = Image.fromarray(to_numpy(result)[0])
result_img.save("img/snow-leopard-pixel.webp")
```

Note the difference in vocabulary between the two. The legacy API uses target_size and patch_size, while the torch API uses pixel_size and thickness. The two parameter names describe the same two ideas, one being the target resolution of the output grid and the other the size of the source pixels being reduced, and the mapping is not spelled out in the README, so it is worth checking which one your code means when you move between them.

The torch path also shows the pipeline shape: pre_resize prepares the image, including the .cuda().half() call that moves the tensor to the GPU in half precision, then pixelize does the work, then to_numpy brings the result back.

The third is the Slang API, which exposes backend contexts and extra options such as sliding-window outline statistics:

```python
from pixeloe.slang import pixelize, get_context

result = pixelize(img, pixel_size=4, thickness=3, context=get_context("cuda"))
result = pixelize(img, pixel_size=4, thickness=3, local_stats="sliding")
```

Backend selection on the torch API is automatic by default, and can be overridden per call or through an environment variable:

```python
result = pixelize(img, pixel_size=4, thickness=3)                   # "auto"
result = pixelize(img, pixel_size=4, thickness=3, backend="torch")  # torch pipeline
result = pixelize(img, pixel_size=4, thickness=3, backend="vulkan") # cuda / vulkan / d3d12 / cpu
```

The PIXELOE_BACKEND environment variable is the one to reach for in a deployed pipeline, because it lets you pin the backend without changing code.

## The Slang backend and the performance claims

The backend story is the most interesting engineering decision in the project.

The whole pipeline is also implemented as Slang compute kernels, and Slang is a shading language that compiles to CUDA, Vulkan, D3D12 or native CPU. The README claims it gives the same results as the torch pipeline and that it is 5-10x faster on GPU and about 3x faster on CPU, and that pixelize() picks the fastest backend that works on your machine automatically.

Same results is the claim that matters. A backend that produced slightly different output would be useless for the purpose, since the whole point is a deterministic image transformation. The README states it plainly: it gives the same results as the torch pipeline.

The torch pipeline's own performance figure is over 180 images per second at batch size 1 on an RTX 4090, with 1920x1080 input and 480x270 output. Batch size 1 is the honest measurement for this kind of work, since the pipeline is per-image.

And the GPU is optional. The library is GPU Free in the sense that all the core logic can be used without GPU, which follows from the numpy and OpenCV path existing at all. So the same algorithm runs on a laptop CPU, and the Slang CPU backend makes it faster there.

The install story follows from the platform matrix. Installing the package also installs slangpy, the Slang backend, on Windows x64, Linux x64 and arm64, and macOS 26 or newer on Apple Silicon. On other platforms PixelOE runs the torch pipeline. The pyproject encodes the same rule as a marker expression, and the dependency comment spells out why: macOS arm64 wheels need macOS 26, which is Darwin 25, and elsewhere pixelize() runs the torch pipeline. The optional-dependencies section also carries a slang extra that requests slangpy where the marker leaves it out, so on an unsupported platform you can install it yourself.

The optional extras are otherwise the demo tooling: gradio with toml, standalone with gradio, toml and pywebview, an all group that combines them, and a dev group with black, build, pytest, pytest-cov, ruff and twine.

## ComfyUI nodes, a CLI, and a demo app

The distribution channels tell you who this is for, and the README lists three of them.

The ComfyUI integration is the most interesting, because ComfyUI is a node-based image generation workflow tool and a pixelization node fits into it as a post-process. The README says a ComfyUI Custom Node implementation is provided in the repository directly and that you just need to clone the repo into the custom_node directory and it will work:

```bash
cd custom_nodes
git clone https://github.com/KohakuBlueleaf/PixelOE
```

Three nodes are provided in the extension: PixelOE for the pixelization itself, OutlineExpansion which only utilises the OutlineExpansion algorithm, and PreResize which resizes based on target pixel image resolution and each pixel's size. Splitting outline expansion and pre-resize into their own nodes is the useful part, because in a ComfyUI graph you can apply them at different points in the pipeline, before and after other operations.

The CLI is the second channel, and the README flags a caveat on it: the CLI in PixelOE is currently using legacy API which will be deprecated in near future. The two primary commands are pixeloe.pixelize for the full pixelization process and pixeloe.outline for outline expansion. The usage output shows the full option set, with the mode flag offering the five downsampling methods, target_size, patch_size, thickness, and the color-related flags: no_color_matching, contrast, saturation and colors. The no_upscale and no_downscale flags control whether the output is scaled back up for display.

The third channel is the Python package itself, installed with pip install pixeloe. Alongside it there is a Gradio demo, installed from requirements-gradio.txt and run with python ./client/demo-gr.py, which comes up on localhost:7860. There is a standalone window variant using requirements-standalone.txt, and the README notes that it may have additional requirements, for example on Linux you must have either QT or GTK with Python extensions installed in order to use pywebview.

The pyproject also registers a third console script, pixeloe.slang, separate from the two legacy ones, with its own CLI taking a backend and target size:

```bash
pixeloe.slang img/snow-leopard.webp out.png --backend cuda --target-size 256 --pixel-size 4
```

The repository has a lot of demo artefacts committed: the demo/ directory is full of webp files named for each source image and each combination of threshold and mode, which is a useful thing to have when you want to compare the five downsampling methods side by side on the same input.

## Conclusion

Adopt PixelOE if you want stylised pixel art from photographs or illustrations and you would rather have deterministic classical image processing than a diffusion model, since the outline expansion and the contrast-aware downscaling are ordinary algorithms you can reason about. Do not adopt it for anything where you need the artistic variation a generative model produces, because the output is a downscaled version of the input rather than a newly generated image. Verify first that your platform is covered by the Slang backend, which ships wheels for Windows x64, Linux x64 and arm64 and macOS 26 or newer on Apple Silicon, that you install the backend explicitly on anything else because the pyproject marker leaves it out, and that the release you pin is one whose CLI you are willing to use, since the CLI is marked as using the legacy API which will be deprecated in the near future.

## FAQ

### What is PixelOE and how does it produce pixel art?

It is a Python library that generates pixel art from standard images using a contrast-aware approach with no AI or neural networks. It expands the outlines of key features first, then applies an intelligent downscale to the target resolution, which preserves fine details and sharp edges.

### Which downscaling modes does PixelOE offer?

Five: center, contrast, k-centroid, bicubic and nearest. The mode is set with the --mode flag on the CLI or the mode argument in the API, and it decides how each output pixel is chosen from the region it represents.

### What is the Slang backend in PixelOE?

The whole pipeline is also implemented as Slang compute kernels that compile to CUDA, Vulkan, D3D12 or native CPU. The README says it gives the same results as the torch pipeline and is 5-10x faster on GPU and about 3x faster on CPU, and pixelize() picks the fastest backend that works on the machine automatically.

### How do I install PixelOE and what does it need?

Run pip install pixeloe. That also installs slangpy, the Slang backend, on Windows x64, Linux x64 and arm64 and macOS 26 or newer on Apple Silicon, and on other platforms PixelOE runs the torch pipeline. The core logic can also be used without a GPU at all.

### Does PixelOE have ComfyUI nodes?

Yes, a ComfyUI Custom Node implementation is included in the repository. You clone the repo into the custom_nodes directory and it works, and three nodes are provided: PixelOE for pixelization, OutlineExpansion for the outline algorithm alone, and PreResize for resizing to the target pixel resolution.

### What are the different Python APIs in PixelOE?

There is a legacy numpy and OpenCV based API described as slow, a torch API that is fast and GPU supported, and a Slang API that exposes backend contexts and extra options such as sliding-window outline statistics. The torch API also accepts a backend argument or reads the PIXELOE_BACKEND environment variable to override the automatic choice.

## Sources

- [Issues](https://github.com/KohakuBlueleaf/PixelOE/issues)
- [KohakuBlueleaf/PixelOE on GitHub](https://github.com/KohakuBlueleaf/PixelOE)
- [License: Apache-2.0](https://github.com/KohakuBlueleaf/PixelOE/blob/main/LICENSE)
- [README](https://github.com/KohakuBlueleaf/PixelOE/blob/main/README.md)
- [Releases](https://github.com/KohakuBlueleaf/PixelOE/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/kohakublueleaf-pixeloe
