pixelcut 1.3.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.
- pixelcut-1.3.0/LICENSE +21 -0
- pixelcut-1.3.0/PKG-INFO +242 -0
- pixelcut-1.3.0/README.md +225 -0
- pixelcut-1.3.0/pixelcut.egg-info/PKG-INFO +242 -0
- pixelcut-1.3.0/pixelcut.egg-info/SOURCES.txt +13 -0
- pixelcut-1.3.0/pixelcut.egg-info/dependency_links.txt +1 -0
- pixelcut-1.3.0/pixelcut.egg-info/entry_points.txt +2 -0
- pixelcut-1.3.0/pixelcut.egg-info/requires.txt +8 -0
- pixelcut-1.3.0/pixelcut.egg-info/top_level.txt +1 -0
- pixelcut-1.3.0/pixelcut.py +829 -0
- pixelcut-1.3.0/pyproject.toml +21 -0
- pixelcut-1.3.0/setup.cfg +4 -0
- pixelcut-1.3.0/tests/test_exact.py +87 -0
- pixelcut-1.3.0/tests/test_more.py +826 -0
- pixelcut-1.3.0/tests/test_parts.py +269 -0
pixelcut-1.3.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 K&K AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
pixelcut-1.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pixelcut
|
|
3
|
+
Version: 1.3.0
|
|
4
|
+
Summary: K&K pixelcut - cut a picture into parts without changing a single pixel
|
|
5
|
+
License: MIT
|
|
6
|
+
Requires-Python: >=3.9
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: numpy<3,>=1.23
|
|
10
|
+
Requires-Dist: opencv-python-headless<5,>=4.7
|
|
11
|
+
Requires-Dist: Pillow<13,>=9.5
|
|
12
|
+
Requires-Dist: scikit-image<1,>=0.20
|
|
13
|
+
Requires-Dist: vtracer<1,>=0.6
|
|
14
|
+
Provides-Extra: test
|
|
15
|
+
Requires-Dist: pytest; extra == "test"
|
|
16
|
+
Dynamic: license-file
|
|
17
|
+
|
|
18
|
+
# K&K pixelcut
|
|
19
|
+
|
|
20
|
+
   
|
|
21
|
+
|
|
22
|
+
[](https://ko-fi.com/kkwonderland)
|
|
23
|
+
|
|
24
|
+
**English in short:** a small command-line tool that cuts an image into wedge-shaped parts (free angles, straight or **zig-zag** edges) **without altering a single pixel**, turns a white background into real transparency (exact colour-to-alpha), lifts a word or element out and re-places it, and writes **hit-area polygons** for touch menus. Parts put back together over white give the original back (max deviation <= 1/255, measured with `--verify` and `compare`). It does *not* generate or redraw images and does not upscale without inventing pixels. Works on drawings and photos. Details below (German).
|
|
25
|
+
|
|
26
|
+
**Ein Bild in Teile zerlegen, ohne ein einziges Pixel zu verändern.**
|
|
27
|
+
*Cut a picture into parts without changing a single pixel.*
|
|
28
|
+
|
|
29
|
+
**Auf einen Blick**
|
|
30
|
+
|
|
31
|
+
- **Exakt:** Teile über Weiß zusammengesetzt = das Original (höchstens 1/255 Abweichung, bei Fotos 0).
|
|
32
|
+
- **Zacken statt Linie:** Keile um eine Mitte, freie Winkel, gerade Kante oder Zickzack.
|
|
33
|
+
- **Echte Transparenz:** weißer Hintergrund wird sauber freigestellt, auch weiche Kanten.
|
|
34
|
+
- **Trefferflächen:** `parts.json` mit Polygon pro Teil, fertig für Touch-Menüs.
|
|
35
|
+
- **Messbar:** `compare` zeigt SSIM und Pixelabweichung, auch für Ergebnisse anderer Werkzeuge.
|
|
36
|
+
|
|
37
|
+
Gebaut von K&K AI. Entstanden bei einer Handy-App: Ein Comic-Bild sollte zum Menü werden (Blase in vier Teile, Zacken statt Linie, das Wort in der Mitte als Knopf), und es durfte **nicht anders aussehen als das Original**.
|
|
38
|
+
|
|
39
|
+

|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Die Idee in drei Sätzen
|
|
44
|
+
|
|
45
|
+
Die meisten "Bild nachbauen"-Werkzeuge zeichnen neu, tracen oder skalieren hoch. Das Ergebnis sieht dann nur *ähnlich* aus.
|
|
46
|
+
pixelcut macht das Gegenteil: Es behält die Original-Pixel und entscheidet nur, **zu welchem Teil jedes Pixel gehört**.
|
|
47
|
+
Legt man die Teile wieder zusammen, kommt das Original zurück, Pixel für Pixel, und das Werkzeug misst das selbst nach (`--verify`, `compare`).
|
|
48
|
+
|
|
49
|
+
**Bedingung:** Das gilt für 8-Bit-Bilder und mit `--gap 0 --edge 0`. Die Standardwerte (`--gap 2.6 --edge 3.2`) schneiden einen sichtbaren Spalt mit Tintenkante, damit man die Teile sieht. Dann weicht das Ergebnis gewollt ab; `--verify` zeigt beide Zahlen. Transparente Bilder werden über Weiß gelegt und 16-Bit-Bilder auf 8 Bit gebracht, beides mit Hinweis.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Download (ohne Python)
|
|
54
|
+
|
|
55
|
+
Fertige Programme für Windows, Linux (x64 und ARM) und Mac (Apple Silicon und Intel) gibt es unter [Releases](https://github.com/CalyieX/pixelcut/releases/latest). Jedes Programm wurde vor dem Hochladen auf seinem eigenen System mit einem Rundlauftest geprüft.
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Linux / Mac: einmal ausführbar machen, dann starten
|
|
59
|
+
chmod +x pixelcut-linux-x64 # bzw. pixelcut-macos-arm64
|
|
60
|
+
./pixelcut-linux-x64 --help
|
|
61
|
+
|
|
62
|
+
# Windows (PowerShell)
|
|
63
|
+
.\pixelcut-windows-x64.exe --help
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Mac: Beim ersten Start meldet macOS evtl. „nicht verifizierter Entwickler“. Dann in den Systemeinstellungen unter „Datenschutz & Sicherheit“ auf „Trotzdem öffnen“ klicken, oder `xattr -d com.apple.quarantine pixelcut-macos-arm64` ausführen. Die Programme sind nicht signiert.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Im Browser (iPhone, iPad, Android, jeder Rechner)
|
|
71
|
+
|
|
72
|
+
**[calyiex.github.io/pixelcut](https://calyiex.github.io/pixelcut/)** – dieselbe Engine läuft direkt im Browser (Pyodide/WebAssembly), nichts wird hochgeladen, nichts muss installiert werden. Bild auswählen, Winkel eintragen, Teile als ZIP speichern; zum Zusammensetzen alle Teile samt `parts.json` wieder auswählen. Auf iPhone/iPad in Safari ab iOS 16; beim ersten Öffnen werden ca. 40 MB geladen, danach liegt es im Cache. Nicht dabei: `trace`, `upscale`, `compare`, `key` (nur `split`, `join`, `alpha`).
|
|
73
|
+
|
|
74
|
+
Bei jedem Commit prüft das CI die Seite in **WebKit (die Engine von Safari/iPhone), Chromium und Firefox**: Bild teilen, wieder zusammensetzen, Abweichung muss 0 sein. Das ist die Safari-Engine auf einem Mac-Rechner, kein echtes iPhone.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Installation
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
git clone https://github.com/CalyieX/pixelcut
|
|
82
|
+
cd pixelcut
|
|
83
|
+
pip install -r requirements.txt # numpy, opencv, Pillow, scikit-image, vtracer
|
|
84
|
+
python pixelcut.py -h
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Alles ist in `requirements.txt` enthalten, auch `trace` (vtracer) und `compare` (SSIM). Für `upscale` lädt das Tool beim ersten Aufruf von selbst die offizielle Real-ESRGAN-Version (ca. 50 MB, einmalig nach `~/.cache/pixelcut`). Du musst nichts weiter einrichten. Läuft Real-ESRGAN auf dem Rechner nicht (ARM-Linux oder keine Vulkan-Grafikkarte), skaliert das Tool stattdessen mit Lanczos und sagt es dazu.
|
|
88
|
+
|
|
89
|
+
Getestet bei jedem Commit auf GitHub Actions: Windows, Linux (x64 und ARM) und macOS (Apple Silicon und Intel), jeweils mit Python 3.9, 3.12 und 3.13. Das Badge oben zeigt den aktuellen Stand. Nur `upscale` mit Real-ESRGAN braucht eine Vulkan-fähige Grafikkarte und x86-64; sonst skaliert das Tool mit Lanczos und sagt das dazu.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Was pixelcut kann
|
|
94
|
+
|
|
95
|
+
### 1. `alpha`: weißen Hintergrund transparent machen, exakt
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
python pixelcut.py alpha bild.png bild_alpha.png --verify
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Standard-Verfahren *Color-to-Alpha* gegen Weiß: Jeder Farbwert wird so in Farbe + Deckkraft zerlegt, dass das Bild **über Weiß wieder genau das Original** ergibt (gemessen: höchstens 0,5 von 255 Abweichung). Auch weiche Kanten und halbtransparente Ränder bleiben richtig. Kein Ausschneiden mit Zauberstab, keine Kantenreste.
|
|
102
|
+
|
|
103
|
+
### 2. `split`: in Keile schneiden, mit Zacken und Trefferflächen
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
python pixelcut.py split bild.png out --angles 32,148,214,327 --tooth 18 --depth 9 --only-inside --verify
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
- **Keile um eine Mitte.** Die Mitte ist frei wählbar (`--centre x,y`) oder wird automatisch bestimmt (Schwerpunkt der nicht weißen Fläche).
|
|
110
|
+
- **Freie Winkel.** `--angles` gibt die Trennlinien an (0 = rechts, 90 = unten). Sie dürfen **ungleich und schräg** sein, also keine Viertel, sondern zum Beispiel ein X, dessen Arme nicht gleich verteilt sind.
|
|
111
|
+
- **Gerade oder Zacken.** `--depth 0` = gerade Linie. Mit `--depth` und `--tooth` wird aus der Linie ein Zickzack mit scharfen Zähnen.
|
|
112
|
+
- **Spalt und Tintenkante.** `--gap` lässt einen schmalen Spalt zwischen den Teilen, `--edge` zeichnet eine dünne dunkle Kante an die Schnittkante (Comic-Look). Beides lässt sich auf 0 stellen.
|
|
113
|
+
- **Nur die Hauptform schneiden.** `--only-inside` schneidet nur den größten zusammenhängenden Bereich. Wolken, Sterne und Punkte drumherum bleiben ganz und gehören jeweils einem einzigen Teil (dem, in dem die meiste Fläche liegt).
|
|
114
|
+
- **Trefferflächen.** `parts.json` enthält pro Teil `polygon` (größte Außenkontur), `polygons` (alle getrennten Flächen mit ihren Löchern) und den dicksten Punkt (guter Platz für ein Symbol). Damit baut man Touch-Menüs, Klickflächen und Hotspots. Im Original-Projekt: Android `Path` + `Region`.
|
|
115
|
+
- **Fotos.** `--opaque` lässt jedes Pixel deckend, damit helle Bildstellen nicht angetastet werden.
|
|
116
|
+
|
|
117
|
+
Ausgabe: `part_0.png … part_N.png` (RGBA, gleiche Größe wie das Original, nur die Pixel des Teils sind sichtbar) und `parts.json`.
|
|
118
|
+
|
|
119
|
+
### 3. `join`: Teile wieder zusammensetzen
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
python pixelcut.py join out nachbau.png
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Legt alle `part_*.png` über Weiß aufeinander. Das ist der exakte "Nachbau". Mit `--gap 0 --edge 0` geschnitten, ergibt das Ergebnis das Original.
|
|
126
|
+
|
|
127
|
+
### 4. `compare`: messen statt glauben
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
python pixelcut.py compare original.png nachbau.png
|
|
131
|
+
# SSIM 1.0000 mean |diff| 0.000 max |diff| 0
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Ähnlichkeit (SSIM, 1,0 = identisch), mittlere und größte Pixelabweichung. Nutzbar für jedes Bildpaar, auch für Ergebnisse anderer Werkzeuge.
|
|
135
|
+
|
|
136
|
+
### 5. `key`: ein Element herausheben, verkleinern, in die Mitte setzen
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
python pixelcut.py key bild.png out --box 172,170,428,310 --scale 0.55
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Hebt ein Element (zum Beispiel ein Wort) aus einer Fläche heraus, **mit den Original-Pixeln**, verkleinert es und setzt es in die Mitte. Die Lücke wird mit der Flächenfarbe gefüllt. Ausgabe: `base.png` (Bild ohne Element), `element.png` (Element auf transparentem Grund), `preview.png`.
|
|
143
|
+
Voraussetzung: Der Rand der Box (`--box`) liegt auf **einfarbiger Fläche**, sonst stimmt die Füllfarbe nicht.
|
|
144
|
+
|
|
145
|
+
### 6. `trace` und `upscale` (nur zum Vergleichen)
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
python pixelcut.py trace bild.png bild.svg --render bild_trace.png # vtracer
|
|
149
|
+
python pixelcut.py upscale bild.png gross.png # holt Real-ESRGAN beim ersten Mal selbst
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Zwei Fremdverfahren, damit man selbst messen kann, wie weit sie vom Original abweichen. Beide **ändern Pixel** und sind nicht mehr exakt.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Was pixelcut NICHT kann
|
|
157
|
+
|
|
158
|
+
Bitte vorher lesen, das spart Zeit.
|
|
159
|
+
|
|
160
|
+
1. **Es erzeugt kein Bild aus dem Nichts.** Es braucht das Original. Es gibt keine Text-zu-Bild-Funktion, kein "male mir so etwas".
|
|
161
|
+
2. **Es bildet ein Bild nicht ohne Vorlage nach.** Wer ein Bild "neu aufbauen" will, ohne dass es abweicht, braucht das Original als Quelle. Ein Bild, das nicht vom Original zu unterscheiden sein soll, **ist** das Original. Alles, was neu zeichnet (Hand, KI, Tracer), weicht ab. Die Zahlen unten zeigen, wie viel.
|
|
162
|
+
3. **Es macht Bilder nicht größer, ohne Pixel zu erfinden.** Mehr Auflösung geht nur durch Rechnen. `upscale` nutzt dafür Real-ESRGAN, das neue Pixel erfindet. Das Ergebnis ist schärfer, aber nicht mehr exakt.
|
|
163
|
+
4. **Keine Form-Erkennung, keine Objekte.** Es schneidet nach Geometrie (Winkel um eine Mitte), nicht nach Inhalt. Es erkennt keine Personen, Gegenstände oder Texte.
|
|
164
|
+
5. **Keine freien Polygone oder Raster.** `split` schneidet Keile um **eine** Mitte. Für Raster gibt es gute fertige Werkzeuge (zum Beispiel `image-slicer`), für freie Formen Grafikprogramme.
|
|
165
|
+
6. **`key` ist einfach gebaut.** Es erkennt das Element als "alles, was von der Hintergrundfarbe abweicht". Bei Verlauf, Muster oder Foto als Hintergrund liegt es daneben. Das Füllen der Lücke ist eine glatte Fläche (keine Textur, kein Inpainting).
|
|
166
|
+
7. **`alpha` ist nur für weiße Hintergründe.** Andere Hintergrundfarben oder Fotos mit weißem Himmel werden nicht sauber freigestellt (bei Fotos `--opaque` benutzen).
|
|
167
|
+
8. **Keine Animation, keine Videos, keine Vektorgrafik.** Nur Rastergrafik (PNG, JPEG usw.). Ausgabe ist PNG mit Alphakanal.
|
|
168
|
+
9. **Bei Spalt und Tintenkante ist das Ergebnis nicht mehr bit-gleich.** Wer `--gap` und `--edge` benutzt, schneidet bewusst Pixel weg und malt eine Kante. Das ist ein Gestaltungswerkzeug. Exakt zusammensetzen geht mit `--gap 0 --edge 0`.
|
|
169
|
+
10. **Kein Farbmanagement.** Es rechnet in sRGB-Werten, ICC-Profile werden ignoriert.
|
|
170
|
+
11. **Keine Schnittstelle für Programme.** Nur die Kommandozeile (und die Python-Datei zum Einbinden), keine grafische Oberfläche.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Messungen
|
|
175
|
+
|
|
176
|
+
### Foto-Test
|
|
177
|
+
|
|
178
|
+
Foto (Katze, CC0, 451 × 300): jeweils nachgebaut und mit `compare` gegen das Original gemessen.
|
|
179
|
+
|
|
180
|
+
| Weg | SSIM | Mittlere Abweichung | Maximale Abweichung |
|
|
181
|
+
|---|---|---|---|
|
|
182
|
+
| **pixelcut** (`split` + `join`) | **1.0000** | **0.000** | **0** |
|
|
183
|
+
| Bicubic 4x hoch und wieder runter | 0.9956 | 0.661 | 15 |
|
|
184
|
+
| Real-ESRGAN 4x hoch und wieder runter | 0.9513 | 3.438 | 93 |
|
|
185
|
+
| vtracer (als Vektor neu gezeichnet) | 0.8686 | 5.263 | 151 |
|
|
186
|
+
|
|
187
|
+

|
|
188
|
+
|
|
189
|
+
Ausschnitt 3x vergrößert. Nur pixelcut ist vom Original nicht zu unterscheiden.
|
|
190
|
+
|
|
191
|
+
### Zeichnung (Comic-Bild)
|
|
192
|
+
|
|
193
|
+
| Verfahren | SSIM |
|
|
194
|
+
|---|---|
|
|
195
|
+
| [vtracer](https://github.com/visioncortex/vtracer) (Nachzeichnen, Standardwerte des Tools) | 0,96 |
|
|
196
|
+
| Farbquantisierung + Konturen ([image-to-svg](https://github.com/oaustegard/claude-skills)) | 0,78 |
|
|
197
|
+
| **pixelcut** (Original-Pixel) | ≈ 1,00 mit `--gap 0 --edge 0` (höchstens 0,5 von 255 bei der Zeichnung, 0,00 beim Foto) |
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Beispiele
|
|
202
|
+
|
|
203
|
+
| Zeichnung (Demo) | Zerlegt, Teile über Weiß | Foto (CC0, scikit-image), zerlegt |
|
|
204
|
+
|---|---|---|
|
|
205
|
+
|  |  |  |
|
|
206
|
+
|
|
207
|
+
`key` auf der Demo (Wort verkleinert und zentriert, Lücke gefüllt):
|
|
208
|
+
|
|
209
|
+

|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Tests
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
pip install -e ".[test]"
|
|
217
|
+
pytest -q
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
145 Tests. Sie prüfen die gespeicherten Dateien: Rundlauf split + join ist exakt (Zeichnung, Foto, gerade und Zickzack), die Teile überlappen nicht, Polygone, Winkel, Mitte, Größe und dickster Punkt stimmen mit den Teilen überein, `compare`, `key` und `alpha` rechnen richtig, `join` verweigert fehlende oder falsch große Teile, `split` fasst fremde Dateien nicht an, und schlechte Eingaben ergeben eine klare Fehlerzeile. Eingebaute Fehler (Mutationen) werden gefangen.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Wie es im Detail funktioniert
|
|
225
|
+
|
|
226
|
+
- **Color-to-Alpha:** `alpha = 1 − min(R, G, B)`, Farbe = `(Pixel − (1 − alpha)) / alpha`. Über Weiß zusammengesetzt ergibt das wieder den Pixelwert.
|
|
227
|
+
- **Keile:** Für jedes Pixel wird der Winkel zur Mitte berechnet. Der Keil ergibt sich aus den sortierten Trennwinkeln.
|
|
228
|
+
- **Zacken:** Pro Trennlinie wird die Entfernung des Pixels von der Linie mit einer Dreieckswelle verglichen. Wer links der verschobenen Linie liegt, gehört zum einen Keil, wer rechts liegt, zum anderen. So haben beide Teile dieselbe Zackenkante ohne Lücke (außer dem gewollten Spalt).
|
|
229
|
+
- **Trefferflächen:** Aus der Maske jedes Teils wird die Außenkontur gezogen und vereinfacht. Der dickste Punkt kommt aus der Distanztransformation.
|
|
230
|
+
- **Key:** Hintergrundfarbe = Median des Box-Rands. Alles, was weiter als `--threshold` davon entfernt ist, gehört zum Element. Löcher darin werden gefüllt, die Lücke danach weich mit der Flächenfarbe überblendet.
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Lizenz
|
|
235
|
+
|
|
236
|
+
MIT. Das Foto stammt aus `skimage.data` (CC0). Die Demo-Grafik ist selbst erzeugt (`make_demo.py`).
|
|
237
|
+
|
|
238
|
+
Mit Claude Code von K&K AI gebaut.
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
Gefällt dir pixelcut? Ein Kaffee hilft, es weiterzubauen: [ko-fi.com/kkwonderland](https://ko-fi.com/kkwonderland)
|
pixelcut-1.3.0/README.md
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# K&K pixelcut
|
|
2
|
+
|
|
3
|
+
   
|
|
4
|
+
|
|
5
|
+
[](https://ko-fi.com/kkwonderland)
|
|
6
|
+
|
|
7
|
+
**English in short:** a small command-line tool that cuts an image into wedge-shaped parts (free angles, straight or **zig-zag** edges) **without altering a single pixel**, turns a white background into real transparency (exact colour-to-alpha), lifts a word or element out and re-places it, and writes **hit-area polygons** for touch menus. Parts put back together over white give the original back (max deviation <= 1/255, measured with `--verify` and `compare`). It does *not* generate or redraw images and does not upscale without inventing pixels. Works on drawings and photos. Details below (German).
|
|
8
|
+
|
|
9
|
+
**Ein Bild in Teile zerlegen, ohne ein einziges Pixel zu verändern.**
|
|
10
|
+
*Cut a picture into parts without changing a single pixel.*
|
|
11
|
+
|
|
12
|
+
**Auf einen Blick**
|
|
13
|
+
|
|
14
|
+
- **Exakt:** Teile über Weiß zusammengesetzt = das Original (höchstens 1/255 Abweichung, bei Fotos 0).
|
|
15
|
+
- **Zacken statt Linie:** Keile um eine Mitte, freie Winkel, gerade Kante oder Zickzack.
|
|
16
|
+
- **Echte Transparenz:** weißer Hintergrund wird sauber freigestellt, auch weiche Kanten.
|
|
17
|
+
- **Trefferflächen:** `parts.json` mit Polygon pro Teil, fertig für Touch-Menüs.
|
|
18
|
+
- **Messbar:** `compare` zeigt SSIM und Pixelabweichung, auch für Ergebnisse anderer Werkzeuge.
|
|
19
|
+
|
|
20
|
+
Gebaut von K&K AI. Entstanden bei einer Handy-App: Ein Comic-Bild sollte zum Menü werden (Blase in vier Teile, Zacken statt Linie, das Wort in der Mitte als Knopf), und es durfte **nicht anders aussehen als das Original**.
|
|
21
|
+
|
|
22
|
+

|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Die Idee in drei Sätzen
|
|
27
|
+
|
|
28
|
+
Die meisten "Bild nachbauen"-Werkzeuge zeichnen neu, tracen oder skalieren hoch. Das Ergebnis sieht dann nur *ähnlich* aus.
|
|
29
|
+
pixelcut macht das Gegenteil: Es behält die Original-Pixel und entscheidet nur, **zu welchem Teil jedes Pixel gehört**.
|
|
30
|
+
Legt man die Teile wieder zusammen, kommt das Original zurück, Pixel für Pixel, und das Werkzeug misst das selbst nach (`--verify`, `compare`).
|
|
31
|
+
|
|
32
|
+
**Bedingung:** Das gilt für 8-Bit-Bilder und mit `--gap 0 --edge 0`. Die Standardwerte (`--gap 2.6 --edge 3.2`) schneiden einen sichtbaren Spalt mit Tintenkante, damit man die Teile sieht. Dann weicht das Ergebnis gewollt ab; `--verify` zeigt beide Zahlen. Transparente Bilder werden über Weiß gelegt und 16-Bit-Bilder auf 8 Bit gebracht, beides mit Hinweis.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Download (ohne Python)
|
|
37
|
+
|
|
38
|
+
Fertige Programme für Windows, Linux (x64 und ARM) und Mac (Apple Silicon und Intel) gibt es unter [Releases](https://github.com/CalyieX/pixelcut/releases/latest). Jedes Programm wurde vor dem Hochladen auf seinem eigenen System mit einem Rundlauftest geprüft.
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Linux / Mac: einmal ausführbar machen, dann starten
|
|
42
|
+
chmod +x pixelcut-linux-x64 # bzw. pixelcut-macos-arm64
|
|
43
|
+
./pixelcut-linux-x64 --help
|
|
44
|
+
|
|
45
|
+
# Windows (PowerShell)
|
|
46
|
+
.\pixelcut-windows-x64.exe --help
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Mac: Beim ersten Start meldet macOS evtl. „nicht verifizierter Entwickler“. Dann in den Systemeinstellungen unter „Datenschutz & Sicherheit“ auf „Trotzdem öffnen“ klicken, oder `xattr -d com.apple.quarantine pixelcut-macos-arm64` ausführen. Die Programme sind nicht signiert.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Im Browser (iPhone, iPad, Android, jeder Rechner)
|
|
54
|
+
|
|
55
|
+
**[calyiex.github.io/pixelcut](https://calyiex.github.io/pixelcut/)** – dieselbe Engine läuft direkt im Browser (Pyodide/WebAssembly), nichts wird hochgeladen, nichts muss installiert werden. Bild auswählen, Winkel eintragen, Teile als ZIP speichern; zum Zusammensetzen alle Teile samt `parts.json` wieder auswählen. Auf iPhone/iPad in Safari ab iOS 16; beim ersten Öffnen werden ca. 40 MB geladen, danach liegt es im Cache. Nicht dabei: `trace`, `upscale`, `compare`, `key` (nur `split`, `join`, `alpha`).
|
|
56
|
+
|
|
57
|
+
Bei jedem Commit prüft das CI die Seite in **WebKit (die Engine von Safari/iPhone), Chromium und Firefox**: Bild teilen, wieder zusammensetzen, Abweichung muss 0 sein. Das ist die Safari-Engine auf einem Mac-Rechner, kein echtes iPhone.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Installation
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
git clone https://github.com/CalyieX/pixelcut
|
|
65
|
+
cd pixelcut
|
|
66
|
+
pip install -r requirements.txt # numpy, opencv, Pillow, scikit-image, vtracer
|
|
67
|
+
python pixelcut.py -h
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Alles ist in `requirements.txt` enthalten, auch `trace` (vtracer) und `compare` (SSIM). Für `upscale` lädt das Tool beim ersten Aufruf von selbst die offizielle Real-ESRGAN-Version (ca. 50 MB, einmalig nach `~/.cache/pixelcut`). Du musst nichts weiter einrichten. Läuft Real-ESRGAN auf dem Rechner nicht (ARM-Linux oder keine Vulkan-Grafikkarte), skaliert das Tool stattdessen mit Lanczos und sagt es dazu.
|
|
71
|
+
|
|
72
|
+
Getestet bei jedem Commit auf GitHub Actions: Windows, Linux (x64 und ARM) und macOS (Apple Silicon und Intel), jeweils mit Python 3.9, 3.12 und 3.13. Das Badge oben zeigt den aktuellen Stand. Nur `upscale` mit Real-ESRGAN braucht eine Vulkan-fähige Grafikkarte und x86-64; sonst skaliert das Tool mit Lanczos und sagt das dazu.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Was pixelcut kann
|
|
77
|
+
|
|
78
|
+
### 1. `alpha`: weißen Hintergrund transparent machen, exakt
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
python pixelcut.py alpha bild.png bild_alpha.png --verify
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Standard-Verfahren *Color-to-Alpha* gegen Weiß: Jeder Farbwert wird so in Farbe + Deckkraft zerlegt, dass das Bild **über Weiß wieder genau das Original** ergibt (gemessen: höchstens 0,5 von 255 Abweichung). Auch weiche Kanten und halbtransparente Ränder bleiben richtig. Kein Ausschneiden mit Zauberstab, keine Kantenreste.
|
|
85
|
+
|
|
86
|
+
### 2. `split`: in Keile schneiden, mit Zacken und Trefferflächen
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
python pixelcut.py split bild.png out --angles 32,148,214,327 --tooth 18 --depth 9 --only-inside --verify
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
- **Keile um eine Mitte.** Die Mitte ist frei wählbar (`--centre x,y`) oder wird automatisch bestimmt (Schwerpunkt der nicht weißen Fläche).
|
|
93
|
+
- **Freie Winkel.** `--angles` gibt die Trennlinien an (0 = rechts, 90 = unten). Sie dürfen **ungleich und schräg** sein, also keine Viertel, sondern zum Beispiel ein X, dessen Arme nicht gleich verteilt sind.
|
|
94
|
+
- **Gerade oder Zacken.** `--depth 0` = gerade Linie. Mit `--depth` und `--tooth` wird aus der Linie ein Zickzack mit scharfen Zähnen.
|
|
95
|
+
- **Spalt und Tintenkante.** `--gap` lässt einen schmalen Spalt zwischen den Teilen, `--edge` zeichnet eine dünne dunkle Kante an die Schnittkante (Comic-Look). Beides lässt sich auf 0 stellen.
|
|
96
|
+
- **Nur die Hauptform schneiden.** `--only-inside` schneidet nur den größten zusammenhängenden Bereich. Wolken, Sterne und Punkte drumherum bleiben ganz und gehören jeweils einem einzigen Teil (dem, in dem die meiste Fläche liegt).
|
|
97
|
+
- **Trefferflächen.** `parts.json` enthält pro Teil `polygon` (größte Außenkontur), `polygons` (alle getrennten Flächen mit ihren Löchern) und den dicksten Punkt (guter Platz für ein Symbol). Damit baut man Touch-Menüs, Klickflächen und Hotspots. Im Original-Projekt: Android `Path` + `Region`.
|
|
98
|
+
- **Fotos.** `--opaque` lässt jedes Pixel deckend, damit helle Bildstellen nicht angetastet werden.
|
|
99
|
+
|
|
100
|
+
Ausgabe: `part_0.png … part_N.png` (RGBA, gleiche Größe wie das Original, nur die Pixel des Teils sind sichtbar) und `parts.json`.
|
|
101
|
+
|
|
102
|
+
### 3. `join`: Teile wieder zusammensetzen
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
python pixelcut.py join out nachbau.png
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Legt alle `part_*.png` über Weiß aufeinander. Das ist der exakte "Nachbau". Mit `--gap 0 --edge 0` geschnitten, ergibt das Ergebnis das Original.
|
|
109
|
+
|
|
110
|
+
### 4. `compare`: messen statt glauben
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
python pixelcut.py compare original.png nachbau.png
|
|
114
|
+
# SSIM 1.0000 mean |diff| 0.000 max |diff| 0
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Ähnlichkeit (SSIM, 1,0 = identisch), mittlere und größte Pixelabweichung. Nutzbar für jedes Bildpaar, auch für Ergebnisse anderer Werkzeuge.
|
|
118
|
+
|
|
119
|
+
### 5. `key`: ein Element herausheben, verkleinern, in die Mitte setzen
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
python pixelcut.py key bild.png out --box 172,170,428,310 --scale 0.55
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Hebt ein Element (zum Beispiel ein Wort) aus einer Fläche heraus, **mit den Original-Pixeln**, verkleinert es und setzt es in die Mitte. Die Lücke wird mit der Flächenfarbe gefüllt. Ausgabe: `base.png` (Bild ohne Element), `element.png` (Element auf transparentem Grund), `preview.png`.
|
|
126
|
+
Voraussetzung: Der Rand der Box (`--box`) liegt auf **einfarbiger Fläche**, sonst stimmt die Füllfarbe nicht.
|
|
127
|
+
|
|
128
|
+
### 6. `trace` und `upscale` (nur zum Vergleichen)
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
python pixelcut.py trace bild.png bild.svg --render bild_trace.png # vtracer
|
|
132
|
+
python pixelcut.py upscale bild.png gross.png # holt Real-ESRGAN beim ersten Mal selbst
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Zwei Fremdverfahren, damit man selbst messen kann, wie weit sie vom Original abweichen. Beide **ändern Pixel** und sind nicht mehr exakt.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Was pixelcut NICHT kann
|
|
140
|
+
|
|
141
|
+
Bitte vorher lesen, das spart Zeit.
|
|
142
|
+
|
|
143
|
+
1. **Es erzeugt kein Bild aus dem Nichts.** Es braucht das Original. Es gibt keine Text-zu-Bild-Funktion, kein "male mir so etwas".
|
|
144
|
+
2. **Es bildet ein Bild nicht ohne Vorlage nach.** Wer ein Bild "neu aufbauen" will, ohne dass es abweicht, braucht das Original als Quelle. Ein Bild, das nicht vom Original zu unterscheiden sein soll, **ist** das Original. Alles, was neu zeichnet (Hand, KI, Tracer), weicht ab. Die Zahlen unten zeigen, wie viel.
|
|
145
|
+
3. **Es macht Bilder nicht größer, ohne Pixel zu erfinden.** Mehr Auflösung geht nur durch Rechnen. `upscale` nutzt dafür Real-ESRGAN, das neue Pixel erfindet. Das Ergebnis ist schärfer, aber nicht mehr exakt.
|
|
146
|
+
4. **Keine Form-Erkennung, keine Objekte.** Es schneidet nach Geometrie (Winkel um eine Mitte), nicht nach Inhalt. Es erkennt keine Personen, Gegenstände oder Texte.
|
|
147
|
+
5. **Keine freien Polygone oder Raster.** `split` schneidet Keile um **eine** Mitte. Für Raster gibt es gute fertige Werkzeuge (zum Beispiel `image-slicer`), für freie Formen Grafikprogramme.
|
|
148
|
+
6. **`key` ist einfach gebaut.** Es erkennt das Element als "alles, was von der Hintergrundfarbe abweicht". Bei Verlauf, Muster oder Foto als Hintergrund liegt es daneben. Das Füllen der Lücke ist eine glatte Fläche (keine Textur, kein Inpainting).
|
|
149
|
+
7. **`alpha` ist nur für weiße Hintergründe.** Andere Hintergrundfarben oder Fotos mit weißem Himmel werden nicht sauber freigestellt (bei Fotos `--opaque` benutzen).
|
|
150
|
+
8. **Keine Animation, keine Videos, keine Vektorgrafik.** Nur Rastergrafik (PNG, JPEG usw.). Ausgabe ist PNG mit Alphakanal.
|
|
151
|
+
9. **Bei Spalt und Tintenkante ist das Ergebnis nicht mehr bit-gleich.** Wer `--gap` und `--edge` benutzt, schneidet bewusst Pixel weg und malt eine Kante. Das ist ein Gestaltungswerkzeug. Exakt zusammensetzen geht mit `--gap 0 --edge 0`.
|
|
152
|
+
10. **Kein Farbmanagement.** Es rechnet in sRGB-Werten, ICC-Profile werden ignoriert.
|
|
153
|
+
11. **Keine Schnittstelle für Programme.** Nur die Kommandozeile (und die Python-Datei zum Einbinden), keine grafische Oberfläche.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Messungen
|
|
158
|
+
|
|
159
|
+
### Foto-Test
|
|
160
|
+
|
|
161
|
+
Foto (Katze, CC0, 451 × 300): jeweils nachgebaut und mit `compare` gegen das Original gemessen.
|
|
162
|
+
|
|
163
|
+
| Weg | SSIM | Mittlere Abweichung | Maximale Abweichung |
|
|
164
|
+
|---|---|---|---|
|
|
165
|
+
| **pixelcut** (`split` + `join`) | **1.0000** | **0.000** | **0** |
|
|
166
|
+
| Bicubic 4x hoch und wieder runter | 0.9956 | 0.661 | 15 |
|
|
167
|
+
| Real-ESRGAN 4x hoch und wieder runter | 0.9513 | 3.438 | 93 |
|
|
168
|
+
| vtracer (als Vektor neu gezeichnet) | 0.8686 | 5.263 | 151 |
|
|
169
|
+
|
|
170
|
+

|
|
171
|
+
|
|
172
|
+
Ausschnitt 3x vergrößert. Nur pixelcut ist vom Original nicht zu unterscheiden.
|
|
173
|
+
|
|
174
|
+
### Zeichnung (Comic-Bild)
|
|
175
|
+
|
|
176
|
+
| Verfahren | SSIM |
|
|
177
|
+
|---|---|
|
|
178
|
+
| [vtracer](https://github.com/visioncortex/vtracer) (Nachzeichnen, Standardwerte des Tools) | 0,96 |
|
|
179
|
+
| Farbquantisierung + Konturen ([image-to-svg](https://github.com/oaustegard/claude-skills)) | 0,78 |
|
|
180
|
+
| **pixelcut** (Original-Pixel) | ≈ 1,00 mit `--gap 0 --edge 0` (höchstens 0,5 von 255 bei der Zeichnung, 0,00 beim Foto) |
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Beispiele
|
|
185
|
+
|
|
186
|
+
| Zeichnung (Demo) | Zerlegt, Teile über Weiß | Foto (CC0, scikit-image), zerlegt |
|
|
187
|
+
|---|---|---|
|
|
188
|
+
|  |  |  |
|
|
189
|
+
|
|
190
|
+
`key` auf der Demo (Wort verkleinert und zentriert, Lücke gefüllt):
|
|
191
|
+
|
|
192
|
+

|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Tests
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
pip install -e ".[test]"
|
|
200
|
+
pytest -q
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
145 Tests. Sie prüfen die gespeicherten Dateien: Rundlauf split + join ist exakt (Zeichnung, Foto, gerade und Zickzack), die Teile überlappen nicht, Polygone, Winkel, Mitte, Größe und dickster Punkt stimmen mit den Teilen überein, `compare`, `key` und `alpha` rechnen richtig, `join` verweigert fehlende oder falsch große Teile, `split` fasst fremde Dateien nicht an, und schlechte Eingaben ergeben eine klare Fehlerzeile. Eingebaute Fehler (Mutationen) werden gefangen.
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Wie es im Detail funktioniert
|
|
208
|
+
|
|
209
|
+
- **Color-to-Alpha:** `alpha = 1 − min(R, G, B)`, Farbe = `(Pixel − (1 − alpha)) / alpha`. Über Weiß zusammengesetzt ergibt das wieder den Pixelwert.
|
|
210
|
+
- **Keile:** Für jedes Pixel wird der Winkel zur Mitte berechnet. Der Keil ergibt sich aus den sortierten Trennwinkeln.
|
|
211
|
+
- **Zacken:** Pro Trennlinie wird die Entfernung des Pixels von der Linie mit einer Dreieckswelle verglichen. Wer links der verschobenen Linie liegt, gehört zum einen Keil, wer rechts liegt, zum anderen. So haben beide Teile dieselbe Zackenkante ohne Lücke (außer dem gewollten Spalt).
|
|
212
|
+
- **Trefferflächen:** Aus der Maske jedes Teils wird die Außenkontur gezogen und vereinfacht. Der dickste Punkt kommt aus der Distanztransformation.
|
|
213
|
+
- **Key:** Hintergrundfarbe = Median des Box-Rands. Alles, was weiter als `--threshold` davon entfernt ist, gehört zum Element. Löcher darin werden gefüllt, die Lücke danach weich mit der Flächenfarbe überblendet.
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Lizenz
|
|
218
|
+
|
|
219
|
+
MIT. Das Foto stammt aus `skimage.data` (CC0). Die Demo-Grafik ist selbst erzeugt (`make_demo.py`).
|
|
220
|
+
|
|
221
|
+
Mit Claude Code von K&K AI gebaut.
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
Gefällt dir pixelcut? Ein Kaffee hilft, es weiterzubauen: [ko-fi.com/kkwonderland](https://ko-fi.com/kkwonderland)
|