Pixel Rearrangement Tool — Keyboard-Navigated Terminal UI
Project description
██████╗ ██╗██╗ ██╗███████╗██╗ ██╗███████╗██╗ ██████╗ █████╗ ████████╗██╗ ██████╗ ███╗ ██╗
██╔══██╗██║╚██╗██╔╝██╔════╝██║ ██║██╔════╝██║██╔════╝██╔══██╗╚══██╔══╝██║██╔═══██╗████╗ ██║
██████╔╝██║ ╚███╔╝ █████╗ ██║ ██║█████╗ ██║██║ ███████║ ██║ ██║██║ ██║██╔██╗ ██║
██╔═══╝ ██║ ██╔██╗ ██╔══╝ ██║ ██║██╔══╝ ██║██║ ██╔══██║ ██║ ██║██║ ██║██║╚██╗██║
██║ ██║██╔╝ ██╗███████╗███████╗██║██║ ██║╚██████╗██║ ██║ ██║ ██║╚██████╔╝██║ ╚████║
╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝
No pixels created. No pixels destroyed. Only rearranged.
◈ What Is This?
Pixelification is a terminal tool built on a single elegant constraint:
Every pixel in the output must come from the source. Nothing is invented.
It uses optimal transport via colour sorting to rearrange pixels — either between two images or across video frames — creating hypnotic, mathematically-grounded transformations. Think of it as a pixel teleporter: your source image's pixels physically migrate to approximate the structure of a target.
◈ Modes
▸ Image Mode
Rearrange pixels from a source image to approximate the layout of a target image, then watch a 60-frame pixel-sliding animation.
┌──────────────────────────────────────────────────────────────────────┐
│ │
│ SOURCE TARGET RECONSTRUCTION │
│ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │ 🌆 │ │ 🌊 │ │ ✦ ✦ │ ← pixels sliding │
│ │ │ ──────▶ │ │ ──────▶ │ ✦ │ into place │
│ │ │ │ │ │ ✦ ✦ │ │
│ └──────┘ └──────┘ └──────┘ │
│ │
└──────────────────────────────────────────────────────────────────────┘
How it works — in three steps:
1 ╔═══════════════════╗ 2 ╔═══════════════════╗ 3 ╔════════════════════╗
║ SORT BY COLOUR ║ ║ MAP BY RANK ║ ║ ANIMATE ║
║ ║ ║ ║ ║ ║
║ lum → hue → sat ║ ──▶ ║ rank i (source) ║ ──▶ ║ 60-frame lerp ║
║ ║ ║ → position of ║ ║ all pixels move ║
║ darkest = 0 ║ ║ rank i (target) ║ ║ simultaneously ║
║ lightest = N-1 ║ ║ ║ ║ ║
╚═══════════════════╝ ╚═══════════════════╝ ╚════════════════════╝
| Step | What happens |
|---|---|
| Sort | Every pixel in both images is ranked by luminance, then hue, then saturation |
| Map | Source pixel with rank i teleports to where target pixel with rank i lives |
| Animate | Each pixel slides from origin to destination over 60 frames via linear interpolation |
When multiple pixels land on the same display cell, their colours are averaged — a natural blending effect.
▸ Video Mode
Rearrange every frame of a source video (or a still image looped as a video) to match the frames of a target video.
Frame 0 ──[sort]──┬──[rank-map]──▶ Output Frame 0 ──┐
Frame 1 ──[sort]──┼──[rank-map]──▶ Output Frame 1 ├──▶ video file
... │ ... │
Frame N ──[sort]──┴──[rank-map]──▶ Output Frame N ──┘
Key differences from Image Mode:
| Feature | Image Mode | Video Mode |
|---|---|---|
| Animation | 60-frame pixel-slide | None — direct sort + write |
| Aspect ratio handling | N/A | Black bars to preserve content |
| Still image as source | ✗ | ✓ looped for every target frame |
| Progress feedback | Visual window | Terminal progress bar |
Status: Video: [████████████░░░░░░] 62.0% (124/200)
◈ Installation
Using uv (Recommended)
Install Pixelification as a global tool:
uv tool install pixelification
Run it from anywhere:
pixelification
Using pip
pip install pixelification
Then run:
pixelification
Using pipx
No installation required:
pipx run pixelification
◈ Hardware Support
| Platform | Acceleration | Notes |
|---|---|---|
| NVIDIA GPU | ✅ CUDA 13 | Full GPU acceleration via cupy-cuda13x[ctk] |
| Intel CPU/GPU | ⚡ CPU (NumPy) | Automatic fallback, no extra packages needed |
On first launch, Pixelification writes a small runtime config to your OS config directory with the detected hardware-acceleration flag. It just works.
◈ Usage
A keyboard-navigated terminal UI opens immediately:
■ Pixel Rearrangement Tool
● Rearrange Images sort pixels between two images
○ Rearrange Videos sort frames between two videos
○ Quit exit the application
Keyboard Controls
| Key | Action |
|---|---|
↑ ↓ |
Navigate menu items |
Enter |
Select highlighted item |
1–N |
Jump directly to item N |
q / Esc |
Quit |
Image Mode
- Select your source image
- Select your target image
- Watch the rearrangement play out in an OpenCV window — three panels: Source · Target · Reconstruction
- Press
ESCorqto quit the animation - Click "Save Result Image" to export a PNG
Video Mode
- Select a source video (or still image — it'll be looped)
- Select a target video
- Watch the terminal progress bar as frames are processed
- Result plays in an OpenCV window — loops until
ESC/qor window close - Click "Save Result Video" to export
◈ Requirements
Python ≥ 3.10
OpenCV cv2
NumPy
prompt_toolkit
# Optional — installed automatically on supported platforms:
cupy-cuda13x[ctk] # NVIDIA CUDA acceleration (Linux / Windows)
python3-tk # Linux only — for file dialog fallback
# sudo apt install python3-tk
◈ Rust Component
The codebase also includes Aster Browser — a Rust-based Win32 application.
⚠️ Windows only.
cargo build --release
◈ The Algorithm (Deep Dive)
For the curious: this is discrete optimal transport solved via sorting. The classical OT problem asks "how do I move mass from distribution A to distribution B at minimum cost?" When cost = squared distance and both distributions have the same total mass, the solution on a 1D sorted line is simply to pair the ith element of one with the ith element of the other.
Pixelification extends this to colour space: pixels are projected onto a 1D ordering by (luminance, hue, saturation), making the sort a tractable proxy for true 2D optimal transport. The result is perceptually coherent pixel migration — similar tones find similar homes.
flowchart LR
A[Source Image] --> C[lexsort\nlum → hue → sat]
B[Target Image] --> D[lexsort\nlum → hue → sat]
C --> E[s_order]
D --> F[t_order]
E --> G[forward mapping\nforward at s_order = t_order]
F --> G
G --> H[per-pixel position lerp]
H --> I[scatter render\nnp.add.at]
I --> J[60-frame animation]
Every pixel has a story. This tool just reassigns the ending.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pixelification-1.2.1.tar.gz.
File metadata
- Download URL: pixelification-1.2.1.tar.gz
- Upload date:
- Size: 51.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5b1a405af83f8f66173287379e7260af76213d916ff7e0ae196608ed71f07407
|
|
| MD5 |
b19ecc6e5f621e05a3d5281874113126
|
|
| BLAKE2b-256 |
95571beff7497ba8aa5cdc3c5dd91877a9670214de4646d70995831e50b13c04
|
File details
Details for the file pixelification-1.2.1-py3-none-any.whl.
File metadata
- Download URL: pixelification-1.2.1-py3-none-any.whl
- Upload date:
- Size: 14.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3dec7586ee77a74ea122ee3973ed165d2315a9558ba8523a68a459b7d2bd0b16
|
|
| MD5 |
62947b612a0f0ddafe8d76781090efec
|
|
| BLAKE2b-256 |
36453c605e8610dc5b17995be3642399f71b7da4b186fc46716bbc53d1fbea47
|