pixelification 1.2.0__tar.gz → 1.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. pixelification-1.2.1/PKG-INFO +257 -0
  2. pixelification-1.2.1/README.md +245 -0
  3. pixelification-1.2.1/main.py +9 -0
  4. {pixelification-1.2.0 → pixelification-1.2.1}/pyproject.toml +7 -0
  5. pixelification-1.2.1/requirements.txt +6 -0
  6. {pixelification-1.2.0 → pixelification-1.2.1}/src/pixelification/main.py +178 -39
  7. pixelification-1.2.1/src/pixelification/runtime.py +74 -0
  8. pixelification-1.2.1/uv.lock +390 -0
  9. pixelification-1.2.0/PKG-INFO +0 -149
  10. pixelification-1.2.0/README.md +0 -139
  11. pixelification-1.2.0/main.py +0 -6
  12. {pixelification-1.2.0 → pixelification-1.2.1}/.github/workflows/publish.yml +0 -0
  13. {pixelification-1.2.0 → pixelification-1.2.1}/.gitignore +0 -0
  14. {pixelification-1.2.0 → pixelification-1.2.1}/.python-version +0 -0
  15. {pixelification-1.2.0 → pixelification-1.2.1}/Cargo.lock +0 -0
  16. {pixelification-1.2.0 → pixelification-1.2.1}/Cargo.toml +0 -0
  17. {pixelification-1.2.0 → pixelification-1.2.1}/src/app/mod.rs +0 -0
  18. {pixelification-1.2.0 → pixelification-1.2.1}/src/config/mod.rs +0 -0
  19. {pixelification-1.2.0 → pixelification-1.2.1}/src/drag/mod.rs +0 -0
  20. {pixelification-1.2.0 → pixelification-1.2.1}/src/events/mod.rs +0 -0
  21. {pixelification-1.2.0 → pixelification-1.2.1}/src/main.rs +0 -0
  22. {pixelification-1.2.0 → pixelification-1.2.1}/src/pixelification/__init__.py +0 -0
  23. {pixelification-1.2.0 → pixelification-1.2.1}/src/state/mod.rs +0 -0
  24. {pixelification-1.2.0 → pixelification-1.2.1}/src/ui/animated.rs +0 -0
  25. {pixelification-1.2.0 → pixelification-1.2.1}/src/ui/bitmap.rs +0 -0
  26. {pixelification-1.2.0 → pixelification-1.2.1}/src/ui/brush.rs +0 -0
  27. {pixelification-1.2.0 → pixelification-1.2.1}/src/ui/color.rs +0 -0
  28. {pixelification-1.2.0 → pixelification-1.2.1}/src/ui/font.rs +0 -0
  29. {pixelification-1.2.0 → pixelification-1.2.1}/src/ui/mod.rs +0 -0
  30. {pixelification-1.2.0 → pixelification-1.2.1}/src/ui/render.rs +0 -0
  31. {pixelification-1.2.0 → pixelification-1.2.1}/src/webview/mod.rs +0 -0
  32. {pixelification-1.2.0 → pixelification-1.2.1}/src/win32.rs +0 -0
@@ -0,0 +1,257 @@
1
+ Metadata-Version: 2.4
2
+ Name: pixelification
3
+ Version: 1.2.1
4
+ Summary: Pixel Rearrangement Tool — Keyboard-Navigated Terminal UI
5
+ Requires-Python: >=3.10
6
+ Requires-Dist: numpy>=1.20.0
7
+ Requires-Dist: opencv-python>=4.0.0
8
+ Requires-Dist: prompt-toolkit>=3.0.0
9
+ Provides-Extra: cuda
10
+ Requires-Dist: cupy-cuda13x[ctk]; extra == 'cuda'
11
+ Description-Content-Type: text/markdown
12
+
13
+ <div align="center">
14
+
15
+ ```
16
+ ██████╗ ██╗██╗ ██╗███████╗██╗ ██╗███████╗██╗ ██████╗ █████╗ ████████╗██╗ ██████╗ ███╗ ██╗
17
+ ██╔══██╗██║╚██╗██╔╝██╔════╝██║ ██║██╔════╝██║██╔════╝██╔══██╗╚══██╔══╝██║██╔═══██╗████╗ ██║
18
+ ██████╔╝██║ ╚███╔╝ █████╗ ██║ ██║█████╗ ██║██║ ███████║ ██║ ██║██║ ██║██╔██╗ ██║
19
+ ██╔═══╝ ██║ ██╔██╗ ██╔══╝ ██║ ██║██╔══╝ ██║██║ ██╔══██║ ██║ ██║██║ ██║██║╚██╗██║
20
+ ██║ ██║██╔╝ ██╗███████╗███████╗██║██║ ██║╚██████╗██║ ██║ ██║ ██║╚██████╔╝██║ ╚████║
21
+ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝
22
+ ```
23
+
24
+ **No pixels created. No pixels destroyed. Only rearranged.**
25
+
26
+ [![Python](https://img.shields.io/badge/Python-3.10+-1a1a2e?style=for-the-badge&logo=python&logoColor=e94560)](https://python.org)
27
+ [![PyPI](https://img.shields.io/badge/PyPI-pixelification-1a1a2e?style=for-the-badge&logo=pypi&logoColor=e94560)](https://pypi.org/project/pixelification)
28
+ [![CUDA](https://img.shields.io/badge/CUDA-13-1a1a2e?style=for-the-badge&logo=nvidia&logoColor=76b900)](https://developer.nvidia.com/cuda-toolkit)
29
+ [![License](https://img.shields.io/badge/License-MIT-1a1a2e?style=for-the-badge)](LICENSE)
30
+
31
+ </div>
32
+
33
+ ---
34
+
35
+ ## ◈ What Is This?
36
+
37
+ **Pixelification** is a terminal tool built on a single elegant constraint:
38
+
39
+ > *Every pixel in the output must come from the source. Nothing is invented.*
40
+
41
+ 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.
42
+
43
+ ---
44
+
45
+ ## ◈ Modes
46
+
47
+ ### ▸ Image Mode
48
+
49
+ Rearrange pixels from a **source image** to approximate the layout of a **target image**, then watch a 60-frame pixel-sliding animation.
50
+
51
+ ```
52
+ ┌──────────────────────────────────────────────────────────────────────┐
53
+ │ │
54
+ │ SOURCE TARGET RECONSTRUCTION │
55
+ │ ┌──────┐ ┌──────┐ ┌──────┐ │
56
+ │ │ 🌆 │ │ 🌊 │ │ ✦ ✦ │ ← pixels sliding │
57
+ │ │ │ ──────▶ │ │ ──────▶ │ ✦ │ into place │
58
+ │ │ │ │ │ │ ✦ ✦ │ │
59
+ │ └──────┘ └──────┘ └──────┘ │
60
+ │ │
61
+ └──────────────────────────────────────────────────────────────────────┘
62
+ ```
63
+
64
+ **How it works — in three steps:**
65
+
66
+ ```
67
+ 1 ╔═══════════════════╗ 2 ╔═══════════════════╗ 3 ╔════════════════════╗
68
+ ║ SORT BY COLOUR ║ ║ MAP BY RANK ║ ║ ANIMATE ║
69
+ ║ ║ ║ ║ ║ ║
70
+ ║ lum → hue → sat ║ ──▶ ║ rank i (source) ║ ──▶ ║ 60-frame lerp ║
71
+ ║ ║ ║ → position of ║ ║ all pixels move ║
72
+ ║ darkest = 0 ║ ║ rank i (target) ║ ║ simultaneously ║
73
+ ║ lightest = N-1 ║ ║ ║ ║ ║
74
+ ╚═══════════════════╝ ╚═══════════════════╝ ╚════════════════════╝
75
+ ```
76
+
77
+ | Step | What happens |
78
+ |------|-------------|
79
+ | **Sort** | Every pixel in both images is ranked by luminance, then hue, then saturation |
80
+ | **Map** | Source pixel with rank *i* teleports to where target pixel with rank *i* lives |
81
+ | **Animate** | Each pixel slides from origin to destination over 60 frames via linear interpolation |
82
+
83
+ > When multiple pixels land on the same display cell, their colours are averaged — a natural blending effect.
84
+
85
+ ---
86
+
87
+ ### ▸ Video Mode
88
+
89
+ Rearrange every frame of a **source video** (or a still image looped as a video) to match the frames of a **target video**.
90
+
91
+ ```
92
+ Frame 0 ──[sort]──┬──[rank-map]──▶ Output Frame 0 ──┐
93
+ Frame 1 ──[sort]──┼──[rank-map]──▶ Output Frame 1 ├──▶ video file
94
+ ... │ ... │
95
+ Frame N ──[sort]──┴──[rank-map]──▶ Output Frame N ──┘
96
+ ```
97
+
98
+ **Key differences from Image Mode:**
99
+
100
+ | Feature | Image Mode | Video Mode |
101
+ |---------|-----------|-----------|
102
+ | Animation | 60-frame pixel-slide | None — direct sort + write |
103
+ | Aspect ratio handling | N/A | Black bars to preserve content |
104
+ | Still image as source | ✗ | ✓ looped for every target frame |
105
+ | Progress feedback | Visual window | Terminal progress bar |
106
+
107
+ ```
108
+ Status: Video: [████████████░░░░░░] 62.0% (124/200)
109
+ ```
110
+
111
+ ---
112
+
113
+ ## ◈ Installation
114
+
115
+ ### Using uv (Recommended)
116
+
117
+ Install Pixelification as a global tool:
118
+
119
+ ```bash
120
+ uv tool install pixelification
121
+ ```
122
+
123
+ Run it from anywhere:
124
+
125
+ ```bash
126
+ pixelification
127
+ ```
128
+
129
+ ---
130
+
131
+ ### Using pip
132
+
133
+ ```bash
134
+ pip install pixelification
135
+ ```
136
+
137
+ Then run:
138
+
139
+ ```bash
140
+ pixelification
141
+ ```
142
+
143
+ ---
144
+
145
+ ### Using pipx
146
+
147
+ No installation required:
148
+
149
+ ```bash
150
+ pipx run pixelification
151
+ ```
152
+ ---
153
+
154
+ ## ◈ Hardware Support
155
+
156
+ | Platform | Acceleration | Notes |
157
+ |----------|-------------|-------|
158
+ | **NVIDIA GPU** | ✅ CUDA 13 | Full GPU acceleration via `cupy-cuda13x[ctk]` |
159
+ | **Intel CPU/GPU** | ⚡ CPU (NumPy) | Automatic fallback, no extra packages needed |
160
+
161
+ > On first launch, Pixelification writes a small runtime config to your OS config directory with the detected hardware-acceleration flag. It just works.
162
+
163
+ ---
164
+
165
+ ## ◈ Usage
166
+
167
+ A keyboard-navigated terminal UI opens immediately:
168
+
169
+ ```
170
+ ■ Pixel Rearrangement Tool
171
+
172
+ ● Rearrange Images sort pixels between two images
173
+ ○ Rearrange Videos sort frames between two videos
174
+ ○ Quit exit the application
175
+ ```
176
+
177
+ ### Keyboard Controls
178
+
179
+ | Key | Action |
180
+ |-----|--------|
181
+ | `↑` `↓` | Navigate menu items |
182
+ | `Enter` | Select highlighted item |
183
+ | `1`–`N` | Jump directly to item *N* |
184
+ | `q` / `Esc` | Quit |
185
+
186
+ ### Image Mode
187
+
188
+ 1. Select your source image
189
+ 2. Select your target image
190
+ 3. Watch the rearrangement play out in an OpenCV window — three panels: **Source · Target · Reconstruction**
191
+ 4. Press `ESC` or `q` to quit the animation
192
+ 5. Click **"Save Result Image"** to export a PNG
193
+
194
+ ### Video Mode
195
+
196
+ 1. Select a source video (or still image — it'll be looped)
197
+ 2. Select a target video
198
+ 3. Watch the terminal progress bar as frames are processed
199
+ 4. Result plays in an OpenCV window — loops until `ESC`/`q` or window close
200
+ 5. Click **"Save Result Video"** to export
201
+
202
+ ---
203
+
204
+ ## ◈ Requirements
205
+
206
+ ```
207
+ Python ≥ 3.10
208
+ OpenCV cv2
209
+ NumPy
210
+ prompt_toolkit
211
+
212
+ # Optional — installed automatically on supported platforms:
213
+ cupy-cuda13x[ctk] # NVIDIA CUDA acceleration (Linux / Windows)
214
+ python3-tk # Linux only — for file dialog fallback
215
+ # sudo apt install python3-tk
216
+ ```
217
+
218
+ ---
219
+
220
+ ## ◈ Rust Component
221
+
222
+ The codebase also includes **Aster Browser** — a Rust-based Win32 application.
223
+
224
+ > ⚠️ Windows only.
225
+
226
+ ```bash
227
+ cargo build --release
228
+ ```
229
+
230
+ ---
231
+
232
+ ## ◈ The Algorithm (Deep Dive)
233
+
234
+ 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 *i*th element of one with the *i*th element of the other.
235
+
236
+ 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.
237
+
238
+ ```
239
+ flowchart LR
240
+ A[Source Image] --> C[lexsort\nlum → hue → sat]
241
+ B[Target Image] --> D[lexsort\nlum → hue → sat]
242
+ C --> E[s_order]
243
+ D --> F[t_order]
244
+ E --> G[forward mapping\nforward at s_order = t_order]
245
+ F --> G
246
+ G --> H[per-pixel position lerp]
247
+ H --> I[scatter render\nnp.add.at]
248
+ I --> J[60-frame animation]
249
+ ```
250
+
251
+ ---
252
+
253
+ <div align="center">
254
+
255
+ *Every pixel has a story. This tool just reassigns the ending.*
256
+
257
+ </div>
@@ -0,0 +1,245 @@
1
+ <div align="center">
2
+
3
+ ```
4
+ ██████╗ ██╗██╗ ██╗███████╗██╗ ██╗███████╗██╗ ██████╗ █████╗ ████████╗██╗ ██████╗ ███╗ ██╗
5
+ ██╔══██╗██║╚██╗██╔╝██╔════╝██║ ██║██╔════╝██║██╔════╝██╔══██╗╚══██╔══╝██║██╔═══██╗████╗ ██║
6
+ ██████╔╝██║ ╚███╔╝ █████╗ ██║ ██║█████╗ ██║██║ ███████║ ██║ ██║██║ ██║██╔██╗ ██║
7
+ ██╔═══╝ ██║ ██╔██╗ ██╔══╝ ██║ ██║██╔══╝ ██║██║ ██╔══██║ ██║ ██║██║ ██║██║╚██╗██║
8
+ ██║ ██║██╔╝ ██╗███████╗███████╗██║██║ ██║╚██████╗██║ ██║ ██║ ██║╚██████╔╝██║ ╚████║
9
+ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝
10
+ ```
11
+
12
+ **No pixels created. No pixels destroyed. Only rearranged.**
13
+
14
+ [![Python](https://img.shields.io/badge/Python-3.10+-1a1a2e?style=for-the-badge&logo=python&logoColor=e94560)](https://python.org)
15
+ [![PyPI](https://img.shields.io/badge/PyPI-pixelification-1a1a2e?style=for-the-badge&logo=pypi&logoColor=e94560)](https://pypi.org/project/pixelification)
16
+ [![CUDA](https://img.shields.io/badge/CUDA-13-1a1a2e?style=for-the-badge&logo=nvidia&logoColor=76b900)](https://developer.nvidia.com/cuda-toolkit)
17
+ [![License](https://img.shields.io/badge/License-MIT-1a1a2e?style=for-the-badge)](LICENSE)
18
+
19
+ </div>
20
+
21
+ ---
22
+
23
+ ## ◈ What Is This?
24
+
25
+ **Pixelification** is a terminal tool built on a single elegant constraint:
26
+
27
+ > *Every pixel in the output must come from the source. Nothing is invented.*
28
+
29
+ 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.
30
+
31
+ ---
32
+
33
+ ## ◈ Modes
34
+
35
+ ### ▸ Image Mode
36
+
37
+ Rearrange pixels from a **source image** to approximate the layout of a **target image**, then watch a 60-frame pixel-sliding animation.
38
+
39
+ ```
40
+ ┌──────────────────────────────────────────────────────────────────────┐
41
+ │ │
42
+ │ SOURCE TARGET RECONSTRUCTION │
43
+ │ ┌──────┐ ┌──────┐ ┌──────┐ │
44
+ │ │ 🌆 │ │ 🌊 │ │ ✦ ✦ │ ← pixels sliding │
45
+ │ │ │ ──────▶ │ │ ──────▶ │ ✦ │ into place │
46
+ │ │ │ │ │ │ ✦ ✦ │ │
47
+ │ └──────┘ └──────┘ └──────┘ │
48
+ │ │
49
+ └──────────────────────────────────────────────────────────────────────┘
50
+ ```
51
+
52
+ **How it works — in three steps:**
53
+
54
+ ```
55
+ 1 ╔═══════════════════╗ 2 ╔═══════════════════╗ 3 ╔════════════════════╗
56
+ ║ SORT BY COLOUR ║ ║ MAP BY RANK ║ ║ ANIMATE ║
57
+ ║ ║ ║ ║ ║ ║
58
+ ║ lum → hue → sat ║ ──▶ ║ rank i (source) ║ ──▶ ║ 60-frame lerp ║
59
+ ║ ║ ║ → position of ║ ║ all pixels move ║
60
+ ║ darkest = 0 ║ ║ rank i (target) ║ ║ simultaneously ║
61
+ ║ lightest = N-1 ║ ║ ║ ║ ║
62
+ ╚═══════════════════╝ ╚═══════════════════╝ ╚════════════════════╝
63
+ ```
64
+
65
+ | Step | What happens |
66
+ |------|-------------|
67
+ | **Sort** | Every pixel in both images is ranked by luminance, then hue, then saturation |
68
+ | **Map** | Source pixel with rank *i* teleports to where target pixel with rank *i* lives |
69
+ | **Animate** | Each pixel slides from origin to destination over 60 frames via linear interpolation |
70
+
71
+ > When multiple pixels land on the same display cell, their colours are averaged — a natural blending effect.
72
+
73
+ ---
74
+
75
+ ### ▸ Video Mode
76
+
77
+ Rearrange every frame of a **source video** (or a still image looped as a video) to match the frames of a **target video**.
78
+
79
+ ```
80
+ Frame 0 ──[sort]──┬──[rank-map]──▶ Output Frame 0 ──┐
81
+ Frame 1 ──[sort]──┼──[rank-map]──▶ Output Frame 1 ├──▶ video file
82
+ ... │ ... │
83
+ Frame N ──[sort]──┴──[rank-map]──▶ Output Frame N ──┘
84
+ ```
85
+
86
+ **Key differences from Image Mode:**
87
+
88
+ | Feature | Image Mode | Video Mode |
89
+ |---------|-----------|-----------|
90
+ | Animation | 60-frame pixel-slide | None — direct sort + write |
91
+ | Aspect ratio handling | N/A | Black bars to preserve content |
92
+ | Still image as source | ✗ | ✓ looped for every target frame |
93
+ | Progress feedback | Visual window | Terminal progress bar |
94
+
95
+ ```
96
+ Status: Video: [████████████░░░░░░] 62.0% (124/200)
97
+ ```
98
+
99
+ ---
100
+
101
+ ## ◈ Installation
102
+
103
+ ### Using uv (Recommended)
104
+
105
+ Install Pixelification as a global tool:
106
+
107
+ ```bash
108
+ uv tool install pixelification
109
+ ```
110
+
111
+ Run it from anywhere:
112
+
113
+ ```bash
114
+ pixelification
115
+ ```
116
+
117
+ ---
118
+
119
+ ### Using pip
120
+
121
+ ```bash
122
+ pip install pixelification
123
+ ```
124
+
125
+ Then run:
126
+
127
+ ```bash
128
+ pixelification
129
+ ```
130
+
131
+ ---
132
+
133
+ ### Using pipx
134
+
135
+ No installation required:
136
+
137
+ ```bash
138
+ pipx run pixelification
139
+ ```
140
+ ---
141
+
142
+ ## ◈ Hardware Support
143
+
144
+ | Platform | Acceleration | Notes |
145
+ |----------|-------------|-------|
146
+ | **NVIDIA GPU** | ✅ CUDA 13 | Full GPU acceleration via `cupy-cuda13x[ctk]` |
147
+ | **Intel CPU/GPU** | ⚡ CPU (NumPy) | Automatic fallback, no extra packages needed |
148
+
149
+ > On first launch, Pixelification writes a small runtime config to your OS config directory with the detected hardware-acceleration flag. It just works.
150
+
151
+ ---
152
+
153
+ ## ◈ Usage
154
+
155
+ A keyboard-navigated terminal UI opens immediately:
156
+
157
+ ```
158
+ ■ Pixel Rearrangement Tool
159
+
160
+ ● Rearrange Images sort pixels between two images
161
+ ○ Rearrange Videos sort frames between two videos
162
+ ○ Quit exit the application
163
+ ```
164
+
165
+ ### Keyboard Controls
166
+
167
+ | Key | Action |
168
+ |-----|--------|
169
+ | `↑` `↓` | Navigate menu items |
170
+ | `Enter` | Select highlighted item |
171
+ | `1`–`N` | Jump directly to item *N* |
172
+ | `q` / `Esc` | Quit |
173
+
174
+ ### Image Mode
175
+
176
+ 1. Select your source image
177
+ 2. Select your target image
178
+ 3. Watch the rearrangement play out in an OpenCV window — three panels: **Source · Target · Reconstruction**
179
+ 4. Press `ESC` or `q` to quit the animation
180
+ 5. Click **"Save Result Image"** to export a PNG
181
+
182
+ ### Video Mode
183
+
184
+ 1. Select a source video (or still image — it'll be looped)
185
+ 2. Select a target video
186
+ 3. Watch the terminal progress bar as frames are processed
187
+ 4. Result plays in an OpenCV window — loops until `ESC`/`q` or window close
188
+ 5. Click **"Save Result Video"** to export
189
+
190
+ ---
191
+
192
+ ## ◈ Requirements
193
+
194
+ ```
195
+ Python ≥ 3.10
196
+ OpenCV cv2
197
+ NumPy
198
+ prompt_toolkit
199
+
200
+ # Optional — installed automatically on supported platforms:
201
+ cupy-cuda13x[ctk] # NVIDIA CUDA acceleration (Linux / Windows)
202
+ python3-tk # Linux only — for file dialog fallback
203
+ # sudo apt install python3-tk
204
+ ```
205
+
206
+ ---
207
+
208
+ ## ◈ Rust Component
209
+
210
+ The codebase also includes **Aster Browser** — a Rust-based Win32 application.
211
+
212
+ > ⚠️ Windows only.
213
+
214
+ ```bash
215
+ cargo build --release
216
+ ```
217
+
218
+ ---
219
+
220
+ ## ◈ The Algorithm (Deep Dive)
221
+
222
+ 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 *i*th element of one with the *i*th element of the other.
223
+
224
+ 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.
225
+
226
+ ```
227
+ flowchart LR
228
+ A[Source Image] --> C[lexsort\nlum → hue → sat]
229
+ B[Target Image] --> D[lexsort\nlum → hue → sat]
230
+ C --> E[s_order]
231
+ D --> F[t_order]
232
+ E --> G[forward mapping\nforward at s_order = t_order]
233
+ F --> G
234
+ G --> H[per-pixel position lerp]
235
+ H --> I[scatter render\nnp.add.at]
236
+ I --> J[60-frame animation]
237
+ ```
238
+
239
+ ---
240
+
241
+ <div align="center">
242
+
243
+ *Every pixel has a story. This tool just reassigns the ending.*
244
+
245
+ </div>
@@ -0,0 +1,9 @@
1
+ import sys
2
+ from pathlib import Path
3
+
4
+ sys.path.insert(0, str(Path(__file__).resolve().parent / "src"))
5
+
6
+ from pixelification.main import main
7
+
8
+ if __name__ == "__main__":
9
+ main()
@@ -4,18 +4,25 @@ dynamic = ["version"]
4
4
  description = "Pixel Rearrangement Tool — Keyboard-Navigated Terminal UI"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
7
+
7
8
  dependencies = [
8
9
  "prompt-toolkit>=3.0.0",
9
10
  "opencv-python>=4.0.0",
10
11
  "numpy>=1.20.0",
11
12
  ]
12
13
 
14
+ [project.optional-dependencies]
15
+ cuda = ["cupy-cuda13x[ctk]"]
16
+
13
17
  [project.scripts]
14
18
  pixelification = "pixelification.main:main"
15
19
 
16
20
  [tool.hatch.version]
17
21
  source = "vcs"
18
22
 
23
+ [tool.hatch.version.raw-options]
24
+ local_scheme = "no-local-version"
25
+
19
26
  [build-system]
20
27
  requires = ["hatchling", "hatch-vcs"]
21
28
  build-backend = "hatchling.build"
@@ -0,0 +1,6 @@
1
+ prompt-toolkit>=3.0.0
2
+ opencv-python>=4.0.0
3
+ numpy>=1.20.0
4
+
5
+ # Optional — CUDA acceleration (NVIDIA GPU required)
6
+ # cupy-cuda13x[ctk]