7d42782c41
Print now offers every format the AI pipeline knows (9x13 to 60x90, DIN A6-A2, squares, poster/frame sizes to 70x100, and the screen ratios as physical sizes). When a picture does not match the target ratio the user picks per image between cropping to fill and keeping the whole picture on a border colour - never a stretch. The module is called Passbilder now; /druck redirects. Fixes two real defects: sharp runs extend after resize, so padded cells came out oversized (a 35x45 mm cell became 35x171 mm with a border), and the grid packer rotated a single portrait photo just because more would fit sideways. Mobile: cards become rows, touch targets ~40px, crop editor as a bottom sheet. Verified at 390/820/1440px - all three produce the same PDF.
131 lines
8.7 KiB
Markdown
131 lines
8.7 KiB
Markdown
# Changelog
|
||
|
||
All notable changes to Klarbild are documented here. Newest first.
|
||
|
||
## 2026-08-18 (2) — Passbildfunktion: all sizes, fit rules, mobile
|
||
|
||
### Added
|
||
- **Renamed to "Passbilder"** — the tab, page and Telegram button now say what it is.
|
||
`/druck` permanently redirects to `/passbilder`.
|
||
- **Every size the AI pipeline knows** is now printable too: 9×13 … 60×90, DIN A6–A2,
|
||
squares, plus poster/frame sizes up to 70×100 and the screen ratios (16:9 "The Frame",
|
||
9:16, 3:2, 4:3, 5:4) as physical measurements. 41 presets in seven groups.
|
||
- **Fit rule per image** — when the picture does not match the target ratio, choose
|
||
**Zuschneiden** (fill the format, crop the overflow — default) or **Rand lassen**
|
||
(keep the whole picture, pad with a border colour: white, black, paper or custom).
|
||
Nothing is ever distorted. Works in the crop editor, the sheet preview, the PDF,
|
||
`/api/print/*` (`fit`, `bg`) and the saved templates.
|
||
- **Mobile layout** — image cards become a row on phones, touch targets grow to ~40 px,
|
||
the crop editor turns into a full-width bottom sheet, no horizontal overflow.
|
||
Verified at 390 / 820 / 1440 px; all three produce the identical PDF.
|
||
|
||
### Fixed
|
||
- **Sheet cells could come out oversized.** sharp applies `extend` *after* `resize`, so
|
||
padding was added on top of the finished size — a 35×45 mm cell became 35×171 mm in
|
||
"Rand lassen" mode, and bleed near an image edge was off too. Crop and padding now run
|
||
in their own pass. Covered by `tests/printrender.test.ts`.
|
||
- **Orientation is no longer overridden.** A single portrait passport photo was laid down
|
||
sideways just because more would fit that way. Rotation now only happens when it
|
||
actually saves a sheet.
|
||
|
||
## 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`.
|
||
- **Seeded sheet templates** — "Kita-Satz (A4)", "Schulsatz klein (A4)", "Passbildbogen 35×45 (A4)"
|
||
and "2 × 10×7,5 auf Fotopapier 10×15". Loading a multi-format template with a single image
|
||
clones that image into every format, so one click produces the whole set.
|
||
- **Margin profiles** — borderless (0 mm), standard (5 mm) and safe (10 mm) as one-click buttons.
|
||
- **Deliver the sheet** — the finished PDF can additionally be pushed to Picdrop, the NAS or any
|
||
extra delivery target (`deliver` in the sheet request).
|
||
- **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
|
||
- **Compose mode** — combine multiple images + a text description into one new image.
|
||
- **Generate mode** — create images from text only, no source needed.
|
||
- **The Frame "extend"** — outpaint more scene around the motif instead of only cropping.
|
||
- **Reuse** — take a finished result back into the studio as a new source to edit further.
|
||
- **Alternatives** — generate additional versions of the same image, grouped with a switcher.
|
||
- **Folders** — filter, rename and delete in the library; per-folder delivery gallery mapping.
|
||
- **Bulk actions** — download selected results as a ZIP, move several into a folder at once.
|
||
- **Thumbnails** — low-res previews for the library grid.
|
||
- **Models** — quality tiers incl. open-source (FLUX.2); the used model is shown per image.
|
||
- **Color tags** — Picdrop-style flags (red / orange / green / final) per image, filterable, and
|
||
written into the companion `.md` metadata.
|
||
- **Tap-to-save** — "Laden" opens the image full-bleed so on iPhone/iPad a long-press offers
|
||
"Save to Photos" (plus a classic file download).
|
||
- **Access control & privacy** — library visibility (own-only vs shared), optional anonymous
|
||
generations (creator hidden from non-admins), admins always see all.
|
||
- **Private sessions** — generate-and-forget: no library entry, no delivery/backup, no stored
|
||
prompt, sources purged, result auto-deleted shortly after. Enabled globally by admin or forced
|
||
per user.
|
||
- **NSFW gate** — models flagged NSFW are only selectable/visible when the admin enables it.
|
||
Operator responsibility; content involving minors is never permitted.
|
||
- **Single-image transform** — compose now accepts one image, so a single photo can be
|
||
transformed by prompt (e.g. "make it an oil painting") and put onto a format.
|
||
- **Multiple delivery targets** — besides the default Picdrop, add any number of FTP/SFTP
|
||
destinations; selectable in the studio ("Wohin?", incl. NAS); a preset or folder can be
|
||
hard-wired to a specific target + gallery.
|
||
- **Backup to any target** — mark any target as a backup destination (like the NAS); one-click
|
||
"back up all images" mirrors to all backup destinations.
|
||
- **Metadata sidecar** — optionally ship a companion `.md` (prompt, model, format …) next to
|
||
each image on Picdrop/NAS/FTP.
|
||
- **Prompt view** — every generated image shows its prompt in the library (with copy).
|
||
- **Preset manager** — save current settings as a preset, load and delete presets.
|
||
- **API token + MCP server** — programmatic access so an assistant can push images from a
|
||
local folder or iMessage into Klarbild (`mcp/klarbild-mcp.mjs`).
|
||
- **The Frame** preset now delivers to its own gallery ("TheFrame-Backgrounds").
|
||
- **Second backup** — mirror every result over SFTP/FTPS to a NAS (works over Tailscale too),
|
||
with a "NAS ✓" badge and a "mirror all existing images" action.
|
||
- **Storage management** — thumbnails, delete sources after processing, auto-retention.
|
||
- **Telegram** — fully button-driven (persistent keyboard + command menu): edit, compose,
|
||
"new image", reuse — no slash commands required.
|
||
- **Reset** — wipe library, jobs and folders cleanly (keeps users, settings, models, recipes),
|
||
guarded by a typed confirmation.
|
||
- **Help page**, in-app **changelog**, and a NAS **reachability diagnostic**.
|
||
|
||
### Fixed / hardened
|
||
- Real per-image cost cap (monthly budget) enforced by the worker.
|
||
- Idempotent job completion (no duplicate delivery/notification).
|
||
- Before/after comparison works for composed images; hidden for text-only results.
|
||
|
||
## 2026-07-22 — Foundation
|
||
|
||
### Added
|
||
- Astro 5 + React islands UI (mobile-first), PostgreSQL, fs/S3 storage abstraction.
|
||
- pg-boss job queue with in-process worker; sharp pipeline (exact cm/dpi print sizes,
|
||
sticker contour).
|
||
- OpenRouter image gateway; admin-managed models.
|
||
- Picdrop delivery over SFTP/FTPS; recipes; library with before/after.
|
||
- Telegram bot (grammY webhook); argon2 auth; AES-256-GCM secret encryption.
|