pixelification 0.1.0__tar.gz → 1.2.0__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.
- pixelification-1.2.0/.github/workflows/publish.yml +24 -0
- {pixelification-0.1.0 → pixelification-1.2.0}/.gitignore +0 -0
- {pixelification-0.1.0 → pixelification-1.2.0}/.python-version +0 -0
- {pixelification-0.1.0 → pixelification-1.2.0}/Cargo.lock +0 -0
- {pixelification-0.1.0 → pixelification-1.2.0}/Cargo.toml +7 -6
- pixelification-1.2.0/PKG-INFO +149 -0
- pixelification-1.2.0/README.md +139 -0
- {pixelification-0.1.0 → pixelification-1.2.0}/main.py +0 -0
- {pixelification-0.1.0 → pixelification-1.2.0}/pyproject.toml +5 -2
- {pixelification-0.1.0 → pixelification-1.2.0}/src/app/mod.rs +0 -0
- {pixelification-0.1.0 → pixelification-1.2.0}/src/config/mod.rs +0 -0
- {pixelification-0.1.0 → pixelification-1.2.0}/src/drag/mod.rs +0 -0
- {pixelification-0.1.0 → pixelification-1.2.0}/src/events/mod.rs +0 -0
- pixelification-1.2.0/src/main.rs +31 -0
- {pixelification-0.1.0 → pixelification-1.2.0}/src/pixelification/__init__.py +0 -0
- pixelification-1.2.0/src/pixelification/main.py +910 -0
- {pixelification-0.1.0 → pixelification-1.2.0}/src/state/mod.rs +0 -0
- {pixelification-0.1.0 → pixelification-1.2.0}/src/ui/animated.rs +0 -0
- {pixelification-0.1.0 → pixelification-1.2.0}/src/ui/bitmap.rs +0 -0
- {pixelification-0.1.0 → pixelification-1.2.0}/src/ui/brush.rs +0 -0
- {pixelification-0.1.0 → pixelification-1.2.0}/src/ui/color.rs +0 -0
- {pixelification-0.1.0 → pixelification-1.2.0}/src/ui/font.rs +0 -0
- {pixelification-0.1.0 → pixelification-1.2.0}/src/ui/mod.rs +0 -0
- {pixelification-0.1.0 → pixelification-1.2.0}/src/ui/render.rs +0 -0
- {pixelification-0.1.0 → pixelification-1.2.0}/src/webview/mod.rs +0 -0
- {pixelification-0.1.0 → pixelification-1.2.0}/src/win32.rs +0 -0
- pixelification-0.1.0/PKG-INFO +0 -88
- pixelification-0.1.0/README.md +0 -78
- pixelification-0.1.0/aster-browser-todo.md +0 -408
- pixelification-0.1.0/src/main.rs +0 -18
- pixelification-0.1.0/src/pixelification/main.py +0 -531
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
publish:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
with:
|
|
16
|
+
fetch-depth: 0
|
|
17
|
+
|
|
18
|
+
- uses: astral-sh/setup-uv@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: '3.12'
|
|
21
|
+
|
|
22
|
+
- run: uv build
|
|
23
|
+
|
|
24
|
+
- run: uv publish --token ${{ secrets.PYPI_API_TOKEN }}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -4,6 +4,13 @@ version = "0.1.0"
|
|
|
4
4
|
edition = "2024"
|
|
5
5
|
|
|
6
6
|
[dependencies]
|
|
7
|
+
serde = { version = "1", features = ["derive"] }
|
|
8
|
+
serde_json = "1"
|
|
9
|
+
toml = "0.8"
|
|
10
|
+
tracing = "0.1"
|
|
11
|
+
tracing-subscriber = { version = "0.3", features = ["json", "env-filter"] }
|
|
12
|
+
|
|
13
|
+
[target.'cfg(windows)'.dependencies]
|
|
7
14
|
windows = { version = "0.60", features = [
|
|
8
15
|
"Win32_Foundation",
|
|
9
16
|
"Win32_UI_WindowsAndMessaging",
|
|
@@ -14,14 +21,8 @@ windows = { version = "0.60", features = [
|
|
|
14
21
|
"Win32_UI_Shell",
|
|
15
22
|
"Win32_UI_HiDpi",
|
|
16
23
|
"Win32_UI_Input_KeyboardAndMouse",
|
|
17
|
-
"Win32_UI_Input_KeyboardAndMouse",
|
|
18
24
|
"Win32_System_Power",
|
|
19
25
|
"Win32_Storage_FileSystem",
|
|
20
26
|
"Win32_Networking_WinSock",
|
|
21
27
|
] }
|
|
22
|
-
serde = { version = "1", features = ["derive"] }
|
|
23
|
-
serde_json = "1"
|
|
24
|
-
toml = "0.8"
|
|
25
|
-
tracing = "0.1"
|
|
26
|
-
tracing-subscriber = { version = "0.3", features = ["json", "env-filter"] }
|
|
27
28
|
webview2-com = "0.39"
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pixelification
|
|
3
|
+
Version: 1.2.0
|
|
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
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
|
|
11
|
+
# Pixelification
|
|
12
|
+
|
|
13
|
+
A terminal tool that rearranges pixels — either between two images or across video frames — using optimal transport via colour sorting.
|
|
14
|
+
|
|
15
|
+
No pixels are created. Every pixel in the output comes from the source, just rearranged.
|
|
16
|
+
|
|
17
|
+
## Modes
|
|
18
|
+
|
|
19
|
+
### Image Mode
|
|
20
|
+
|
|
21
|
+
Rearrange pixels from a **source image** to approximate the layout of a **target image**, then watch a 60-frame pixel-sliding animation.
|
|
22
|
+
|
|
23
|
+
#### How it works
|
|
24
|
+
|
|
25
|
+
```mermaid
|
|
26
|
+
flowchart LR
|
|
27
|
+
A[Source Image] --> C[Color sort<br/>lexsort by<br/>lum→hue→sat]
|
|
28
|
+
B[Target Image] --> D[Color sort<br/>lexsort by<br/>lum→hue→sat]
|
|
29
|
+
C --> E["s_order[i]"]
|
|
30
|
+
D --> F["t_order[i]"]
|
|
31
|
+
E --> G["forward[s_order] = t_order"]
|
|
32
|
+
F --> G
|
|
33
|
+
G --> H[Per-pixel<br/>position lerp]
|
|
34
|
+
H --> I[Scatter render<br/>np.add.at]
|
|
35
|
+
I --> J[60 frames<br/>slide animation]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
1. **Sort by colour** — every pixel in both images is sorted by luminance, then hue, then saturation. The darkest source pixel gets rank 0, the lightest gets rank *N*−1. Same for the target.
|
|
39
|
+
|
|
40
|
+
2. **Map by rank** — a source pixel with rank *i* maps to the target position with rank *i*. This is the optimal transport: the *i*th darkest pixel in the source ends up where the *i*th darkest pixel was in the target.
|
|
41
|
+
|
|
42
|
+
3. **Animate** — each pixel slides from its original position to its mapped position over 60 frames using linear interpolation. All pixels move simultaneously. When multiple pixels land on the same display cell, their colours are averaged.
|
|
43
|
+
|
|
44
|
+
### Video Mode
|
|
45
|
+
|
|
46
|
+
Rearrange every frame of a **source video** (or a still image looped as a video) to match the frames of a **target video**. Each frame pair is processed with the same sort-based algorithm, then the result is written to a temporary video and played back in an OpenCV window.
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
Source frame i ──[color sort]──┐
|
|
50
|
+
├──[rank-map]──→ output frame i ──→ video file
|
|
51
|
+
Target frame i ──[color sort]──┘
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Key differences from Image Mode:**
|
|
55
|
+
- **No pixel-sliding animation** — just the sort + write step, with a progress bar in the terminal
|
|
56
|
+
- **Aspect-ratio handling** — if source and target have different aspect ratios, the narrower video is centered with black bars ("transparent pixels") so content isn't distorted
|
|
57
|
+
- **Source can be a still image** — the same image is looped for every frame of the target video
|
|
58
|
+
- **Explicit save** — video is written to a temp file during processing; click "Save Result Video" to export to your working directory
|
|
59
|
+
|
|
60
|
+
## Installation & Usage
|
|
61
|
+
|
|
62
|
+
### Using uv (Recommended)
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Install from source
|
|
66
|
+
uv tool install .
|
|
67
|
+
|
|
68
|
+
# Or run directly
|
|
69
|
+
uv run pixelification
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### From PyPI
|
|
73
|
+
|
|
74
|
+
Once published, you can install it via:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pip install pixelification
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Then run it:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pixelification
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Reinstall after updates — the CLI command is unchanged:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
uv tool install . --reinstall
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Keyboard Controls
|
|
93
|
+
|
|
94
|
+
A keyboard-navigated terminal interface opens. You start at the main menu:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
■ Pixel Rearrangement Tool
|
|
98
|
+
|
|
99
|
+
● Rearrange Images sort pixels between two images
|
|
100
|
+
○ Rearrange Videos sort frames between two videos
|
|
101
|
+
○ Quit exit the application
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
| Key | Action |
|
|
105
|
+
|-----|--------|
|
|
106
|
+
| `↑` `↓` | Navigate menu items |
|
|
107
|
+
| `Enter` | Select highlighted item |
|
|
108
|
+
| `1`–`N` | Direct shortcut for each item |
|
|
109
|
+
| `q` / `Escape` | Quit |
|
|
110
|
+
|
|
111
|
+
### Image Mode Controls
|
|
112
|
+
|
|
113
|
+
Select source and target images, then run the rearrangement. An OpenCV window opens with three panels:
|
|
114
|
+
|
|
115
|
+
| Source | Target | Reconstruction |
|
|
116
|
+
|--------|--------|----------------|
|
|
117
|
+
| Your image | Layout to approximate | Pixels sliding into place |
|
|
118
|
+
|
|
119
|
+
Press `ESC` or `q` during the animation to quit. Click "Save Result Image" to export the result to a PNG file.
|
|
120
|
+
|
|
121
|
+
### Video Mode Controls
|
|
122
|
+
|
|
123
|
+
Select a source video (or image) and a target video, then run. A progress bar shows in the terminal:
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
Status: Video: [████████░░░░░░░░░░] 62.0% (124/200)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
After processing, the result plays in an OpenCV window (loops until you press `ESC`/`q` or click the X button). Click "Save Result Video" to export.
|
|
130
|
+
|
|
131
|
+
If you use a still image as the source, it's automatically looped for every target frame.
|
|
132
|
+
|
|
133
|
+
## Requirements
|
|
134
|
+
|
|
135
|
+
- Python 3.10+
|
|
136
|
+
- OpenCV (`cv2`)
|
|
137
|
+
- NumPy
|
|
138
|
+
- `prompt_toolkit`
|
|
139
|
+
|
|
140
|
+
Cross-platform support is included for Windows and Linux. On Linux, ensure `tkinter` is installed (e.g., `sudo apt install python3-tk`) for the file dialog fallback.
|
|
141
|
+
|
|
142
|
+
## Rust Component (Aster Browser)
|
|
143
|
+
|
|
144
|
+
The codebase also contains a Rust-based Win32 application. This component is currently only supported on Windows.
|
|
145
|
+
To build the Rust component (Windows only):
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
cargo build --release
|
|
149
|
+
```
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Pixelification
|
|
2
|
+
|
|
3
|
+
A terminal tool that rearranges pixels — either between two images or across video frames — using optimal transport via colour sorting.
|
|
4
|
+
|
|
5
|
+
No pixels are created. Every pixel in the output comes from the source, just rearranged.
|
|
6
|
+
|
|
7
|
+
## Modes
|
|
8
|
+
|
|
9
|
+
### Image Mode
|
|
10
|
+
|
|
11
|
+
Rearrange pixels from a **source image** to approximate the layout of a **target image**, then watch a 60-frame pixel-sliding animation.
|
|
12
|
+
|
|
13
|
+
#### How it works
|
|
14
|
+
|
|
15
|
+
```mermaid
|
|
16
|
+
flowchart LR
|
|
17
|
+
A[Source Image] --> C[Color sort<br/>lexsort by<br/>lum→hue→sat]
|
|
18
|
+
B[Target Image] --> D[Color sort<br/>lexsort by<br/>lum→hue→sat]
|
|
19
|
+
C --> E["s_order[i]"]
|
|
20
|
+
D --> F["t_order[i]"]
|
|
21
|
+
E --> G["forward[s_order] = t_order"]
|
|
22
|
+
F --> G
|
|
23
|
+
G --> H[Per-pixel<br/>position lerp]
|
|
24
|
+
H --> I[Scatter render<br/>np.add.at]
|
|
25
|
+
I --> J[60 frames<br/>slide animation]
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
1. **Sort by colour** — every pixel in both images is sorted by luminance, then hue, then saturation. The darkest source pixel gets rank 0, the lightest gets rank *N*−1. Same for the target.
|
|
29
|
+
|
|
30
|
+
2. **Map by rank** — a source pixel with rank *i* maps to the target position with rank *i*. This is the optimal transport: the *i*th darkest pixel in the source ends up where the *i*th darkest pixel was in the target.
|
|
31
|
+
|
|
32
|
+
3. **Animate** — each pixel slides from its original position to its mapped position over 60 frames using linear interpolation. All pixels move simultaneously. When multiple pixels land on the same display cell, their colours are averaged.
|
|
33
|
+
|
|
34
|
+
### Video Mode
|
|
35
|
+
|
|
36
|
+
Rearrange every frame of a **source video** (or a still image looped as a video) to match the frames of a **target video**. Each frame pair is processed with the same sort-based algorithm, then the result is written to a temporary video and played back in an OpenCV window.
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
Source frame i ──[color sort]──┐
|
|
40
|
+
├──[rank-map]──→ output frame i ──→ video file
|
|
41
|
+
Target frame i ──[color sort]──┘
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Key differences from Image Mode:**
|
|
45
|
+
- **No pixel-sliding animation** — just the sort + write step, with a progress bar in the terminal
|
|
46
|
+
- **Aspect-ratio handling** — if source and target have different aspect ratios, the narrower video is centered with black bars ("transparent pixels") so content isn't distorted
|
|
47
|
+
- **Source can be a still image** — the same image is looped for every frame of the target video
|
|
48
|
+
- **Explicit save** — video is written to a temp file during processing; click "Save Result Video" to export to your working directory
|
|
49
|
+
|
|
50
|
+
## Installation & Usage
|
|
51
|
+
|
|
52
|
+
### Using uv (Recommended)
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Install from source
|
|
56
|
+
uv tool install .
|
|
57
|
+
|
|
58
|
+
# Or run directly
|
|
59
|
+
uv run pixelification
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### From PyPI
|
|
63
|
+
|
|
64
|
+
Once published, you can install it via:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pip install pixelification
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Then run it:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pixelification
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Reinstall after updates — the CLI command is unchanged:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
uv tool install . --reinstall
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Keyboard Controls
|
|
83
|
+
|
|
84
|
+
A keyboard-navigated terminal interface opens. You start at the main menu:
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
■ Pixel Rearrangement Tool
|
|
88
|
+
|
|
89
|
+
● Rearrange Images sort pixels between two images
|
|
90
|
+
○ Rearrange Videos sort frames between two videos
|
|
91
|
+
○ Quit exit the application
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
| Key | Action |
|
|
95
|
+
|-----|--------|
|
|
96
|
+
| `↑` `↓` | Navigate menu items |
|
|
97
|
+
| `Enter` | Select highlighted item |
|
|
98
|
+
| `1`–`N` | Direct shortcut for each item |
|
|
99
|
+
| `q` / `Escape` | Quit |
|
|
100
|
+
|
|
101
|
+
### Image Mode Controls
|
|
102
|
+
|
|
103
|
+
Select source and target images, then run the rearrangement. An OpenCV window opens with three panels:
|
|
104
|
+
|
|
105
|
+
| Source | Target | Reconstruction |
|
|
106
|
+
|--------|--------|----------------|
|
|
107
|
+
| Your image | Layout to approximate | Pixels sliding into place |
|
|
108
|
+
|
|
109
|
+
Press `ESC` or `q` during the animation to quit. Click "Save Result Image" to export the result to a PNG file.
|
|
110
|
+
|
|
111
|
+
### Video Mode Controls
|
|
112
|
+
|
|
113
|
+
Select a source video (or image) and a target video, then run. A progress bar shows in the terminal:
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
Status: Video: [████████░░░░░░░░░░] 62.0% (124/200)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
After processing, the result plays in an OpenCV window (loops until you press `ESC`/`q` or click the X button). Click "Save Result Video" to export.
|
|
120
|
+
|
|
121
|
+
If you use a still image as the source, it's automatically looped for every target frame.
|
|
122
|
+
|
|
123
|
+
## Requirements
|
|
124
|
+
|
|
125
|
+
- Python 3.10+
|
|
126
|
+
- OpenCV (`cv2`)
|
|
127
|
+
- NumPy
|
|
128
|
+
- `prompt_toolkit`
|
|
129
|
+
|
|
130
|
+
Cross-platform support is included for Windows and Linux. On Linux, ensure `tkinter` is installed (e.g., `sudo apt install python3-tk`) for the file dialog fallback.
|
|
131
|
+
|
|
132
|
+
## Rust Component (Aster Browser)
|
|
133
|
+
|
|
134
|
+
The codebase also contains a Rust-based Win32 application. This component is currently only supported on Windows.
|
|
135
|
+
To build the Rust component (Windows only):
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
cargo build --release
|
|
139
|
+
```
|
|
File without changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "pixelification"
|
|
3
|
-
|
|
3
|
+
dynamic = ["version"]
|
|
4
4
|
description = "Pixel Rearrangement Tool — Keyboard-Navigated Terminal UI"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
@@ -13,6 +13,9 @@ dependencies = [
|
|
|
13
13
|
[project.scripts]
|
|
14
14
|
pixelification = "pixelification.main:main"
|
|
15
15
|
|
|
16
|
+
[tool.hatch.version]
|
|
17
|
+
source = "vcs"
|
|
18
|
+
|
|
16
19
|
[build-system]
|
|
17
|
-
requires = ["hatchling"]
|
|
20
|
+
requires = ["hatchling", "hatch-vcs"]
|
|
18
21
|
build-backend = "hatchling.build"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#![cfg_attr(all(not(debug_assertions), windows), windows_subsystem = "windows")]
|
|
2
|
+
|
|
3
|
+
#[cfg(windows)]
|
|
4
|
+
mod app;
|
|
5
|
+
#[cfg(windows)]
|
|
6
|
+
mod ui;
|
|
7
|
+
#[cfg(windows)]
|
|
8
|
+
mod events;
|
|
9
|
+
#[cfg(windows)]
|
|
10
|
+
mod state;
|
|
11
|
+
#[cfg(windows)]
|
|
12
|
+
mod config;
|
|
13
|
+
#[cfg(windows)]
|
|
14
|
+
mod drag;
|
|
15
|
+
#[cfg(windows)]
|
|
16
|
+
mod webview;
|
|
17
|
+
#[cfg(windows)]
|
|
18
|
+
mod win32;
|
|
19
|
+
|
|
20
|
+
#[cfg(windows)]
|
|
21
|
+
fn main() {
|
|
22
|
+
let mut app = app::App::new();
|
|
23
|
+
app.create_window();
|
|
24
|
+
app.run();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
#[cfg(not(windows))]
|
|
28
|
+
fn main() {
|
|
29
|
+
println!("The Aster Browser (Rust component) is currently only supported on Windows.");
|
|
30
|
+
println!("The Python component (pixelification) is available on all platforms.");
|
|
31
|
+
}
|
|
File without changes
|