Files
klarbild/README.md
T
till 210a84dcf8 feat: rename to Drucken, 86 image sizes, fix the distorted crop editor
The crop frame had width:100% together with max-height, so the height was
clamped while the width stayed - the frame lost the target aspect ratio and
object-fit:fill stretched the picture into it. Measured at 390px: frame 0.843
instead of 0.778, picture 8.3% too wide. The width now follows from the allowed
height and the ratio, and the image carries its own aspect-ratio instead of a
second percentage, so it cannot stretch at all.

Dragging was fine but felt dead: at fill zoom the crop sits at the stop in one
axis. The editor now states which way it can move, double-tap zooms, arrow keys
nudge, and the zoom slider shows its factor.

Sizes: 41 -> 86 in ten groups, including US inch sizes, instant-film picture
areas, cards, DIN A0-A7 and eleven aspect ratios as physical sizes.

The tab is called Drucken now; /druck and /passbilder redirect there.
2026-08-19 07:50:44 +00:00

76 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Klarbild
Verwandelt Screenshots und Fundstücke in saubere, druckfertige Bilder — Rahmen und
Shop-Oberflächen entfernen, exakte Fotoformate (30×40 cm etc.), The-Frame-Querformat,
für den Cricut freistellen, und automatisch nach Picdrop ausliefern.
**Claim:** „Screenshot rein, sauberes Bild raus."
## Stack
Astro 5 (SSR, Node standalone) + React-Inseln · Postgres · S3 (MinIO) · pg-boss ·
sharp · pdf-lib (Druckbogen) · grammY (Telegram) · OKLCH-Tokens, kein Tailwind.
Deploy: Gitea → Coolify → Hetzner.
## Entwicklung
```bash
npm install
cp .env.example .env # Werte eintragen
npm run dev
```
Migrationen und Seeds laufen beim Serverstart automatisch. Erststart-Passwörter über
`SEED_TILL_PASSWORD` / `SEED_LEA_PASSWORD`.
## Funktionen (Kurzüberblick)
- **Modi:** Bereinigen (Screenshot säubern/freistellen/formatieren), Umwandeln (ein Bild + Text,
z. B. Foto → Ölgemälde), Kombinieren (mehrere Bilder + Text), Neu erzeugen (nur Text).
- **Formate:** feste cm-/DIN-/Screen-Formate **und frei definierbare** — Schlüssel `WxH` (z. B.
`25x35`) oder `sticker<N>` (`sticker5` = 5×5 cm). Parsing in `src/lib/format.ts`, keine Migration nötig.
- **Dateiformat:** PNG (verlustfrei, Transparenz) oder JPG (klein, Picdrop-freundlich). Global über
`settings.output_ext`, pro Rezept via `recipes.output_ext`, pro Umwandlung im Studio. JPG nur ohne Alpha.
- **Auslieferung:** Picdrop (SFTP/FTPS) + beliebige Zusatzziele; NAS/Backup-Ziele; optionaler
`.md`-Metadaten-Beileger **pro Ziel** schaltbar. Nicht-transparente Ergebnisse gehen als JPG an Picdrop.
- **Bibliothek:** Ordner, Farbmarkierungen, Prompt-Anzeige, Vorher/Nachher, Vollbild + „In Fotos sichern".
- **Rechte/Datenschutz:** Sichtbarkeit (eigene/alle), anonyme Generierungen, private Sessions, NSFW-Gate.
- **Telegram-Bot** (grammY-Webhook) als vollwertiger Website-Ersatz. **API-Token** (`Bearer`) für `/api/*`.
- **Drucken (`/drucken`, ohne KI):** Bilder exakt auf physische Maße bringen (interaktiver Zuschnitt mit
Zoom/Verschieben) und mehrere davon in 100-%-Größe mit **Schnittmarken** auf einen Bogen setzen —
Passbildsatz, Kita-Satz, Sticker. Papier DIN A6A2 inkl. **A3+**, Fotopapier 9×1320×30, Letter/Legal
oder freies Maß. Marken: Eckmarken (0,25 pt, außerhalb des Endformats) oder durchgehende Linien.
Beschnittzugabe 010 mm. Ausgabe: PDF in 1:1 (`pdf-lib`) bzw. Einzelbild mit dpi-Metadaten.
Layout: gleiche Größen → exaktes Raster, gemischte Größen → MaxRects-Packer.
Alle Formate der KI-Generierung sind auch hier wählbar; passt das Bild nicht zum Format,
entscheidet man je Bild zwischen **Zuschneiden** und **Rand lassen** (mit Randfarbe) — nie verzerren.
Kern: `src/lib/paper.ts` (Formate), `src/lib/printlayout.ts` (reine Mathematik, getestet),
`src/lib/printrender.ts` (sharp + pdf-lib). Auch per Telegram („🖨 Drucken") und MCP
(`exact_size`, `print_sheet`).
- **Admin:** Key/Picdrop/Modelle/Nutzer/Kostendeckel/Presets/Speicherverwaltung, Picdrop-Diagnose.
## Datenmodell / Migrationen
Nummerierte SQL in `migrations/`, beim Start automatisch (kein ORM-Push). Wichtige Spalten:
`items.has_alpha`, `jobs.status` (inkl. `failed`), `jobs.finished_at`,
`settings.output_ext` / `recipes.output_ext`, `settings.*_metadata_sidecar`, `delivery_targets.*`,
`print_presets` (Bogen-Vorlagen, `013`).
## Tests
`npm test` — Node-Testrunner über `tsx`. Deckt die Druck-Layoutmathematik ab (Maß-Parsing,
mm → px exakt, Überlappungsfreiheit, Ränder, Beschnittzugabe, Markengeometrie, Mehrseitigkeit).
## Stolpersteine & Lösungen (Learnings)
- **„Bild bei Picdrop ✓, aber nicht in der Galerie":** Fehldiagnose vermeiden — die Dateien lagen die ganze
Zeit **korrekt** per SFTP in `/POSTER LEA` (per Admin → Picdrop → „Ordner anzeigen" verifizierbar). Der
eigentliche Grund war die **Sortierung in der Picdrop-Weboberfläche**, nicht das Format. Unabhängig davon
liefern wir nicht-transparente Ergebnisse jetzt als JPG aus (`src/lib/delivery.ts`, `deliverableBuffer`):
~25 MB PNG → ~2 MB JPG, schneller und handlicher — plus wählbares Ausgabeformat (`output_ext`).
- **„Unbekanntes Format: sticker5":** Seed legte ein Rezept mit Formatschlüssel `sticker5` an, den der
Resolver nicht kannte → jeder Lauf schlug fehl. Lösung: generisches Parsen von `sticker<N>`/`WxH`.
- **Auftrag trotz Fehler grün:** `jobs.status` kannte kein `failed`; alle Positionen fehlgeschlagen wurde
trotzdem `done`. Lösung: Status `failed`, wenn `done=0 && failed>0` (`src/worker.ts` `maybeComplete`).
- **Doppelte Datums-/UUID-Namen:** `\b`-Wortgrenzen greifen nicht an Unterstrichen. Lösung: `\b` entfernt,
Datum/UUID/Hex global ersetzt (`src/lib/pipeline.ts` `cleanMotif`).
- **Content-Type bei gemischten PNG/JPG-Ergebnissen:** `file.ts` snifft jetzt die Magic Bytes.
- **`.tmp-`-Reste auf Picdrop:** früher Temp-Rename-Bug; `cleanupTmp` + Admin-Knopf „Reste aufräumen".
## Status
Reihenfolge und Nachweise siehe `CLAUDE.md`. Anforderungen im Handover-Paket
(`Imagetool-Lea/00..07`). Führend: `01-anforderungen.md`.