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.
Files changed (31) hide show
  1. pixelification-1.2.0/.github/workflows/publish.yml +24 -0
  2. {pixelification-0.1.0 → pixelification-1.2.0}/.gitignore +0 -0
  3. {pixelification-0.1.0 → pixelification-1.2.0}/.python-version +0 -0
  4. {pixelification-0.1.0 → pixelification-1.2.0}/Cargo.lock +0 -0
  5. {pixelification-0.1.0 → pixelification-1.2.0}/Cargo.toml +7 -6
  6. pixelification-1.2.0/PKG-INFO +149 -0
  7. pixelification-1.2.0/README.md +139 -0
  8. {pixelification-0.1.0 → pixelification-1.2.0}/main.py +0 -0
  9. {pixelification-0.1.0 → pixelification-1.2.0}/pyproject.toml +5 -2
  10. {pixelification-0.1.0 → pixelification-1.2.0}/src/app/mod.rs +0 -0
  11. {pixelification-0.1.0 → pixelification-1.2.0}/src/config/mod.rs +0 -0
  12. {pixelification-0.1.0 → pixelification-1.2.0}/src/drag/mod.rs +0 -0
  13. {pixelification-0.1.0 → pixelification-1.2.0}/src/events/mod.rs +0 -0
  14. pixelification-1.2.0/src/main.rs +31 -0
  15. {pixelification-0.1.0 → pixelification-1.2.0}/src/pixelification/__init__.py +0 -0
  16. pixelification-1.2.0/src/pixelification/main.py +910 -0
  17. {pixelification-0.1.0 → pixelification-1.2.0}/src/state/mod.rs +0 -0
  18. {pixelification-0.1.0 → pixelification-1.2.0}/src/ui/animated.rs +0 -0
  19. {pixelification-0.1.0 → pixelification-1.2.0}/src/ui/bitmap.rs +0 -0
  20. {pixelification-0.1.0 → pixelification-1.2.0}/src/ui/brush.rs +0 -0
  21. {pixelification-0.1.0 → pixelification-1.2.0}/src/ui/color.rs +0 -0
  22. {pixelification-0.1.0 → pixelification-1.2.0}/src/ui/font.rs +0 -0
  23. {pixelification-0.1.0 → pixelification-1.2.0}/src/ui/mod.rs +0 -0
  24. {pixelification-0.1.0 → pixelification-1.2.0}/src/ui/render.rs +0 -0
  25. {pixelification-0.1.0 → pixelification-1.2.0}/src/webview/mod.rs +0 -0
  26. {pixelification-0.1.0 → pixelification-1.2.0}/src/win32.rs +0 -0
  27. pixelification-0.1.0/PKG-INFO +0 -88
  28. pixelification-0.1.0/README.md +0 -78
  29. pixelification-0.1.0/aster-browser-todo.md +0 -408
  30. pixelification-0.1.0/src/main.rs +0 -18
  31. 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 }}
@@ -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
- version = "0.1.0"
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"
@@ -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
+ }