Hintergrundverarbeitung, Bildaufbereitung, Sammelexport entfernt
All checks were successful
Build & Deploy / deploy (push) Successful in 1m24s

Auslesen im Hintergrund: /api/scan antwortet, sobald die Karten
freigestellt und gespeichert sind, und stößt die Extraktion als Task an.
Ein Zwanzigerstapel blockierte vorher den Upload für die ganze Dauer
aller Modellaufrufe. Die Oberfläche zeigt "wird gelesen" und lädt nach,
solange etwas offen ist.

Zwei Folgen davon sind mitbehandelt: Beim Schreiben der Ergebnisse steht
COALESCE, damit ein Handeintrag während des Lesens nicht überschrieben
wird, und offene Karten werden beim Start nachgeholt, statt dauerhaft in
der Warteschlange zu hängen.

Bildaufbereitung des Zuschnitts:
- Der Einzug zieht die erkannten Ecken um 1,5 % zur Mitte, damit kein
  Untergrund im Zuschnitt bleibt.
- Die Beleuchtung wird ausgeglichen (Division durch eine weichgezeichnete
  Fassung), damit das Papier weiß wird statt grau. Dunkle Karten bleiben
  unangetastet - bei ihnen ist das Dunkle das Papier, kein Schatten.
- Das Modell meldet die nötige Drehung im Schema; das gespeicherte Bild
  wird entsprechend gedreht. Geometrisch ist die Lage nicht bestimmbar.

Sammelexport entfernt: Der Button "Alle als vCard" ist weg, mit ihm der
Endpunkt /vcf sowie vcard.build_many und db.execute_many, die dadurch
keinen Aufrufer mehr hatten.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Lucas Orth
2026-09-06 12:56:58 +02:00
parent 1f29d5eb27
commit a7fbc15792
12 changed files with 369 additions and 91 deletions

View File

@@ -7,11 +7,23 @@ Kontakt aufs iPhone holen. Selbst gehostete PWA, ein Container.
**Stapelscan.** Ein Foto von zwanzig Karten auf dem Tisch reicht. OpenCV findet
die Kartenrechtecke, entzerrt sie perspektivisch und schneidet sie einzeln aus –
ohne manuelle Nacharbeit. Jeder Zuschnitt geht als Bild an das Vision-Modell,
das Name, Firma, Position und Kontaktdaten als strukturiertes JSON zurückgibt.
Ein vorgeschalteter OCR-Schritt wäre kontraproduktiv: er würde Layout und
Schriftgrößen wegwerfen, also genau die Information, aus der die Feldzuordnung
entsteht.
ohne manuelle Nacharbeit. Der Zuschnitt wird dabei leicht enger gesetzt als die
erkannte Kante, damit kein Untergrund stehen bleibt, und die Beleuchtung wird
ausgeglichen, damit das Papier weiß wird statt grau.
Jeder Zuschnitt geht als Bild an das Vision-Modell, das Name, Firma, Position
und Kontaktdaten als strukturiertes JSON zurückgibt. Ein vorgeschalteter
OCR-Schritt wäre kontraproduktiv: er würde Layout und Schriftgrößen wegwerfen,
also genau die Information, aus der die Feldzuordnung entsteht. Das Modell sagt
außerdem, wie herum die Karte gehört – geometrisch ist das nicht bestimmbar –
und das gespeicherte Bild wird entsprechend gedreht.
**Die Antwort wartet nicht auf das Modell.** Der Scan liefert die freigestellten
Karten sofort zurück, das Auslesen läuft danach im Hintergrund weiter; die
Oberfläche lädt nach. Ein Zwanzigerstapel blockiert damit keine Minute im
Upload. Wer eine Karte in der Zwischenzeit von Hand ergänzt, verliert die
Eingabe nicht – das Modell füllt nur leere Felder. Bricht der Server mitten im
Lauf ab, holt er die offenen Karten beim nächsten Start nach.
**Metadaten.** Aufnahmezeit und GPS kommen aus den EXIF-Daten des Fotos, nicht
aus dem Browser – Karten werden oft erst abends am Schreibtisch abfotografiert,
@@ -24,6 +36,8 @@ Filter für „nicht exportiert“, „unvollständig“ und „mit Erinnerung
**Export.** Ein Tippen auf *In Kontakte speichern* liefert eine vCard 3.0, die
iOS direkt in die Kontakte-App übernimmt. Die Karte gilt danach als exportiert.
Bewusst einzeln: ein Sammelexport schiebt zwanzig Kontakte ungeprüft ins
Adressbuch.
**Notizen und Erinnerungen.** Freitext pro Karte. Erinnerungen mit Termin gehen
als Mail raus; verpasste Termine holt der Scheduler beim nächsten Start nach.