From 21a0a689723119a68902f8b75cd570ee24b19263 Mon Sep 17 00:00:00 2001 From: Till Heidrich Date: Tue, 18 Aug 2026 06:20:46 +0000 Subject: [PATCH] docs: print module in help page, llms.txt, README and changelog --- CHANGELOG.md | 34 +++++++++++++++++++++++++++++++ README.md | 19 +++++++++++++++-- src/pages/anleitung.astro | 43 +++++++++++++++++++++++++++++++++++++-- src/pages/llms.txt.ts | 33 ++++++++++++++++++++++++++++-- 4 files changed, 123 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa807d8..a0fa40b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,40 @@ All notable changes to Klarbild are documented here. Newest first. +## 2026-08-18 — Print module: exact sizes, sheets & crop marks (no AI) + +### Added +- **Print module (`/druck`)** — a lab-style, completely AI-free path: crop, scale and place + images at exact physical sizes. No model call, no cost, no queue. +- **Interactive crop editor** — pan and zoom on a fixed target aspect ratio (rule-of-thirds + overlay); the crop is stored relative (0..1) so it survives any source resolution. +- **Size presets & free input** — biometric passport 35 × 45 mm, 2 × 3 / 3 × 4 / 4 × 5 / 4,5 × 6 cm, + 9 × 13 … 50 × 70 cm, squares, DIN. Free input understands `12x15` (cm), `35x45mm`, `5` + (= 5 × 5 cm) and `4:3/15` (ratio + long edge). +- **Sheet layout** — paper presets DIN A6–A2 incl. **A3+ (329 × 483 mm)**, photo-paper cuts + (9 × 13 … 20 × 30), US Letter/Legal, plus any custom paper size. Portrait/landscape, + printer margin, centering, per-image copy count. +- **Automatic nesting** — identical sizes produce an exact grid; mixed sizes go through a + MaxRects packer that fixes one orientation per format and tries every combination, + so eight passport photos land in the free space next to the 13 × 18. +- **Crop marks** — `corner` (fine 0.25 pt marks outside the trim box, Photoshop/InDesign + convention, 4 mm long / 3 mm offset by default) or `grid` (continuous guides across the + sheet that never cross another image). Gap between images adapts to the chosen marks. +- **Bleed** (0–10 mm) — the image extends past the trim box, edge pixels are copied rather + than stretched; the gap is always ≥ 2 × bleed so neighbouring bleeds cannot overlap. +- **PDF output at 1:1** — the PDF page is exactly the sheet size (pdf-lib), with a footer + stating the sizes, dpi and the "print at 100 %, not fit-to-page" reminder. +- **Single export** — one image at an exact size as PNG/JPG with dpi metadata, plus a + resolution warning when the source cannot hold the requested dpi. +- **Sheet templates** — save the whole sheet setup (paper, marks, formats, counts) as a + reusable preset (`print_presets`, migration `013`). +- **All three entrances** — `/druck` in the web app, `📐 Druckbogen` in Telegram (fully + button-driven, returns an A4 PDF), and the MCP tools `exact_size` / `print_sheet`. +- **API** — `POST /api/print/single`, `GET /api/print/single?size=…` (mm → px calculator), + `POST /api/print/sheet`, `GET|POST|DELETE /api/print/presets`. Documented in `/llms.txt`. +- **Tests** — `tests/printlayout.test.ts` (`npm test`) covers size parsing, exact mm → px, + non-overlap, margins, bleed spacing, mark geometry and multi-sheet paging. + ## 2026-07-23 — Compose, generate & second backup ### Added diff --git a/README.md b/README.md index eebd366..f0d97bc 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,8 @@ für den Cricut freistellen, und automatisch nach Picdrop ausliefern. ## Stack Astro 5 (SSR, Node standalone) + React-Inseln · Postgres · S3 (MinIO) · pg-boss · -sharp · grammY (Telegram) · OKLCH-Tokens, kein Tailwind. Deploy: Gitea → Coolify → Hetzner. +sharp · pdf-lib (Druckbogen) · grammY (Telegram) · OKLCH-Tokens, kein Tailwind. +Deploy: Gitea → Coolify → Hetzner. ## Entwicklung ```bash @@ -31,12 +32,26 @@ Migrationen und Seeds laufen beim Serverstart automatisch. Erststart-Passwörter - **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/*`. +- **Druck (`/druck`, 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 A6–A2 inkl. **A3+**, Fotopapier 9×13–20×30, Letter/Legal + oder freies Maß. Marken: Eckmarken (0,25 pt, außerhalb des Endformats) oder durchgehende Linien. + Beschnittzugabe 0–10 mm. Ausgabe: PDF in 1:1 (`pdf-lib`) bzw. Einzelbild mit dpi-Metadaten. + Layout: gleiche Größen → exaktes Raster, gemischte Größen → MaxRects-Packer. + Kern: `src/lib/paper.ts` (Formate), `src/lib/printlayout.ts` (reine Mathematik, getestet), + `src/lib/printrender.ts` (sharp + pdf-lib). Auch per Telegram („📐 Druckbogen") 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.*`. +`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 diff --git a/src/pages/anleitung.astro b/src/pages/anleitung.astro index 2abe83d..4c8b4d9 100644 --- a/src/pages/anleitung.astro +++ b/src/pages/anleitung.astro @@ -59,7 +59,42 @@ import Base from '../layouts/Base.astro';
-

5 · Alles per Telegram — ohne Befehle

+

5 · Druck — exakte Maße und Schnittmarken (ohne KI)

+

Der Reiter Druck ist der Fotolabor-Teil von Klarbild: kein Modell, keine Kosten, + keine Wartezeit. Nur Zuschnitt, Skalierung und Geometrie.

+
    +
  1. Bilder hochladen (ziehen, ⌘/Strg + V, oder Aus Bibliothek ein fertiges Ergebnis holen).
  2. +
  3. Je Bild das Endmaß wählen — biometrisches Passbild 35 × 45 mm, 3 × 4 cm, 9 × 13, 10 × 15, + 12 × 15, 13 × 18 … oder Eigenes Maß: 12x15 (cm), 35x45mm, + 5 (= 5 × 5 cm) oder 4:3/15 (Verhältnis 4:3, längere Kante 15 cm).
  4. +
  5. Auf das Vorschaubild tippen → Zuschnitt: schieben und zoomen. Das Seitenverhältnis bleibt + fest am Zielformat, verzerrt wird nie.
  6. +
  7. Anzahl je Bild setzen — so entsteht der Passbild- oder Kita-Satz.
  8. +
  9. Papierformat wählen: DIN A6–A2 inklusive A3+ (329 × 483 mm), Fotopapier-Zuschnitte + 9 × 13 bis 20 × 30, US Letter/Legal — oder ein eigenes Papiermaß.
  10. +
  11. Schnitthilfen: Eckmarken (feine Marken außerhalb des Endformats, wie in Photoshop + und InDesign) oder durchgehende Linien über den ganzen Bogen fürs Schneidelineal. + Die durchgehenden Linien laufen nie durch ein anderes Motiv.
  12. +
  13. Druck-PDF erzeugen. Die PDF-Seite hat exakt das Bogenmaß.
  14. +
+

Wichtig beim Drucken: im Druckdialog „Tatsächliche Größe" bzw. „100 %" wählen — + nicht „an Seitengröße anpassen". Sonst stimmt das Maß nicht mehr. Wer randlos drucken kann, + setzt den Rand auf 0; sonst 3–5 mm, sonst schneidet der Drucker die Marken weg.

+ +

Auch per Telegram: Bild schicken → „📐 Druckbogen" → Maß und Anzahl antippen → PDF zurück.

+
+ +
+

6 · Alles per Telegram — ohne Befehle

Einmalig koppeln: im Admin einen Code erzeugen und im Chat mit dem Bot eingeben. Danach läuft alles über die Knöpfe unten im Chat — kein Tippen von Befehlen nötig.

Für Profis gibt es zusätzlich das „/"-Befehlsmenü (/neu, /rezepte, /status) — nötig ist es nicht.

-

6 · Sicherung & sauber neu starten (Admin)

+

7 · Sicherung & sauber neu starten (Admin)

Im Admin-Bereich lässt sich eine zweite Sicherung aufs NAS einrichten (SFTP/FTPS, auch über Tailscale) — jedes fertige Bild wird dann zusätzlich gespiegelt und in der Bibliothek mit „NAS ✓" markiert. Mit „Alle vorhandenen Bilder aufs NAS sichern" lassen sich auch ältere Bilder nachsichern.

@@ -107,6 +144,8 @@ import Base from '../layouts/Base.astro'; .howto li{margin-bottom:6px;} .howto code{font-family:var(--font-mono);font-size:.85em;background:var(--paper);border:1px solid var(--line);border-radius:3px;padding:1px 5px;} .howto .mini{font-size:.82rem;color:var(--soft);margin:8px 0 0;} + .howto .hinweis{background:var(--accent-bg);border-left:3px solid var(--accent);padding:10px 13px;margin:12px 0;font-size:.92rem;line-height:1.55;} + .howto code{font-family:var(--font-mono);font-size:.85em;background:var(--paper);border:1px solid var(--line);border-radius:3px;padding:1px 5px;} @media print{.topbar,.tabbar,.druck{display:none !important;}.howto section{break-inside:avoid;}} diff --git a/src/pages/llms.txt.ts b/src/pages/llms.txt.ts index fcb4845..8fb54aa 100644 --- a/src/pages/llms.txt.ts +++ b/src/pages/llms.txt.ts @@ -12,8 +12,10 @@ const BODY = `# Klarbild > Selbst gehostetes KI-Bildwerkzeug: verwandelt Screenshots und Fundstücke in > saubere, druckfertige Bilder (bereinigen, freistellen, exakte Fotoformate, > The-Frame-Querformat, Sticker mit Kontur), liefert an Picdrop (SFTP/FTPS) -> aus und sichert auf beliebige Backup-Ziele (z. B. NAS). Bedienung über Web, -> Telegram-Bot und HTTP-API/MCP. +> aus und sichert auf beliebige Backup-Ziele (z. B. NAS). Zusätzlich ein +> KI-freies Druckmodul: Bilder exakt auf physische Maße bringen und mehrere +> davon in 100-%-Größe mit Schnittmarken auf einen Druckbogen setzen (PDF). +> Bedienung über Web, Telegram-Bot und HTTP-API/MCP. Basis-URL: https://klarbild.heidrich-digital.de Sprache der Oberfläche: Deutsch. Stack: Astro 5 (SSR) · Postgres · sharp · pg-boss. @@ -57,11 +59,38 @@ Sprache der Oberfläche: Deutsch. Stack: Astro 5 (SSR) · Postgres · sharp · p - GET /api/items/:id/file — Ergebnisbild. Query: ?thumb=1 (Vorschau), ?preview=1 (kleines JPG fürs Vollbild), ?download=1 (als Datei), ?src=1 (Quelle). Content-Type wird aus den Magic Bytes bestimmt (PNG/JPG/WEBP). +## Druckmodul (ohne KI, /druck) +Rein lokale Geometrie: Zuschnitt (sharp) + PDF (pdf-lib). Kein Modell, keine Kosten. +- Maßangaben: \`12x15\` = 12×15 cm · \`35x45mm\` · \`5\` = 5×5 cm · \`4:3/15\` = Verhältnis 4:3, längere Kante 15 cm. +- Papierformate (id): A6,A5,A4,A3,A3plus(329×483 mm),A2, F9x13,F10x15,F13x18,F15x20,F20x30, Letter, Legal — oder freies Maß. +- Bildformate (id): P35x45 (biometrisch), P50x50, K20x30,K30x40,K40x50,K45x60,K60x90, + S9x13,S10x15,S12x15,S13x18,S15x20,S18x24,S20x30,S30x40,S30x45,S40x50,S40x60,S50x70, + Q10x10,Q13x13,Q20x20,Q30x30, DA6,DA5,DA4,DA3. +- Schnitthilfen (marks.mode): \`none\` · \`corner\` (Eckmarken außerhalb des Endformats, Standard 4 mm lang, + 3 mm Versatz, 0,25 pt Haarlinie) · \`grid\` (durchgehende Linien über den Bogen, laufen nie durch ein Motiv). +- Beschnittzugabe (bleedMm): das Bild ragt je Seite darüber hinaus; die Trimmbox bleibt exakt der gewählte Ausschnitt. + Der Abstand zwischen zwei Bildern ist immer ≥ 2 × Beschnittzugabe. +- Platzierung: gleich große Bilder → exaktes Raster; gemischte Größen → MaxRects-Packer mit fester + Ausrichtung je Format (probiert alle Ausrichtungs-Kombinationen und nimmt die mit den wenigsten Bogen). +- Die PDF-Seite hat exakt das Bogenmaß. Beim Drucken „Tatsächliche Größe / 100 %" wählen — nicht „an Seite anpassen". + +- POST /api/print/single — ein Bild exakt auf Maß. Body: { src:{kind:'upload',path}|{kind:'item',id}, + crop?:{x,y,w,h} (relativ 0..1; ohne Angabe mittiger Ausschnitt), size|wMm+hMm, landscape?, dpi?, ext?(jpg|png), bleedMm? }. + Antwort: die Bilddatei. Header: X-Klarbild-Px, X-Klarbild-Real-Dpi, X-Klarbild-Dpi-Ok. +- GET /api/print/single?size=12x15&dpi=300 — nur rechnen: mm → Pixel. +- POST /api/print/sheet — Druckbogen als PDF. Body: { paper:{id}|{size}|{wMm,hMm}, landscape?, marginMm?, + gapMm?, bleedMm?, center?, dpi?, ext?, footer?, marks:{mode,lengthMm?,offsetMm?}, + cells:[{ id, src, crop?, size|wMm+hMm, landscape?, count?, allowRotate? }] }. + Antwort: application/pdf. Header: X-Klarbild-Pages, X-Klarbild-Per-Sheet. +- GET/POST/DELETE /api/print/presets — Bogen-Vorlagen (Papier, Marken, Formate, Stückzahlen). + ## MCP-Server (für Assistenten) Werkzeug \`klarbild\` (mcp/klarbild-mcp.mjs), nutzt denselben API-Token: - list_recipes — verfügbare Rezepte. - process_images — Bilder (lokaler Ordner / URLs) mit einem Rezept verarbeiten lassen. - job_status — Fortschritt/Ergebnis eines Auftrags abfragen. +- exact_size — OHNE KI: ein Bild exakt auf ein Maß bringen, Datei lokal speichern. +- print_sheet — OHNE KI: Druckbogen (mehrere Bilder × Stückzahl, Schnittmarken) als PDF lokal speichern. ## Auslieferung - Picdrop = SFTP/FTPS-Ziel; Galerie = Unterordner unter dem Basispfad. Voller Pfad = Basisordner + Galerie