TEXT kommt aus cell.text (bereinigt, IPA-korrigiert).
POSITIONEN kommen aus word_boxes (exakte OCR-Koordinaten).
Tokens werden 1:1 in Leserichtung zugeordnet.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backend: _ocr_cell_crop speichert jetzt word_boxes mit exakten
Tesseract/RapidOCR Wort-Koordinaten (left, top, width, height)
im Cell-Ergebnis. Absolute Bildkoordinaten, bereits zurueckgemappt.
Frontend: Slide-Hook nutzt word_boxes direkt wenn vorhanden —
jedes Wort wird exakt an seiner OCR-Position platziert. Kein
Pixel-Scanning noetig. Fallback auf alten Slide wenn keine Boxes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Gruppen-Sliding schob nicht weit genug nach rechts. Zurueck zum
Original-Einzelwort-Slide, aber mit den Fixes:
- fontRatio=1.0 (konsistente Schriftgroesse wie Fallback)
- Token-Breiten aus medianCh * 0.7 / refFontSize (statt totalInk)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Vorher: split(/\s+/) zerlegte alles in Einzelwoerter, verlor die
Spaltenstruktur (3+ Spaces zwischen Gruppen). Woerter stauten sich links.
Jetzt: split(/\s{3,}/) erhält Gruppen wie im Cluster-Modus. Jede Gruppe
wird als Einheit von links nach rechts geschoben bis Tinte gefunden.
Breite = max(gemessene Textbreite, tatsaechliche Tintenbreite).
fontRatio=1.0, kein Wort geht verloren.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fontRatio war 0.65 (35% kleiner als Fallback-Rendering). Jetzt 1.0
wie beim Fallback. Token-Breiten berechnet aus measureText skaliert
auf die tatsaechlich gerenderte Schriftgroesse (medianCh * 0.7).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Schriftgroesse wird jetzt GLOBAL aus der medianen Zellhoehe berechnet
(65% der Zellhoehe als Ziel-Font). Alle Tokens bekommen dieselbe
konsistente Groesse. Die Slide-Logik bestimmt nur noch die x-Position.
Vorher: Scale pro Zelle aus Ink-Span/Textbreite -> inkonsistente Groessen.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
totalInk zaehlte nur dunkle Pixel-Spalten (Striche), ignorierte
Luecken zwischen Buchstaben. Scale war dadurch viel zu klein,
Schrift unlesbar. Jetzt wird der Ink-Span (erstes bis letztes
dunkles Pixel) als Referenz fuer die Textbreite verwendet.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Neuer Hook useSlideWordPositions: Schiebt alle erkannten Woerter von links
nach rechts ueber die Pixel-Projektion bis jedes Wort auf seiner Tinte
einrastet. Kein Wort geht verloren, keine Cluster-Matching-Regeln noetig.
Toggle-Button (Slide/Cluster) in der Overlay-Toolbar zum Umschalten.
Bestehender Cluster-Algorithmus bleibt als Alternative erhalten.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Zwei wesentliche Verbesserungen:
1. Multi-group: Gruppen werden per Best-Fit-Breite den Clustern
zugeordnet statt naiv links-nach-rechts. Damit wird z.B.
"Kokosnuss" dem DE-Spalten-Cluster zugeordnet statt dem
breiteren Box-Cluster.
2. Single-group Fallback: verwendet den BREITESTEN Cluster statt
first-to-last Span. Verhindert dass Streupixel von benachbarten
Seitenbereichen den Text nach links ziehen.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Box-Rahmen werden vom OCR als einzelne Symbole wie "|" oder ">"
erkannt und als eigene Text-Gruppen behandelt. Das verfaelscht die
Cluster-Zuordnung weil diese Artefakte entweder keinen eigenen
Cluster erzeugen oder den falschen Cluster zugewiesen bekommen.
Fix: Gruppen mit max 2 Zeichen ohne Buchstaben/Ziffern werden mit
der benachbarten Gruppe zusammengefuehrt bevor die Cluster-Zuordnung
laeuft.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wenn mehr Pixel-Cluster als Text-Gruppen existieren (z.B. wegen
Box-Rahmenlinien), werden jetzt die N breitesten Cluster ausgewaehlt
statt naiv clusters[i]→groups[i] zuzuordnen. Text-Cluster sind
breiter als Rahmenlinien-Cluster.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Vorher: wenn Text mehr Wort-Gruppen hatte als Pixel-Cluster gefunden
wurden (z.B. bei Box-Rahmen die Cluster zusammenmergen), wurde die
Zelle komplett uebersprungen → Fallback bei x=0%.
Jetzt: Fallback auf Single-Span Positionierung (first→last Cluster)
statt Skip. Damit wird der Text immer korrekt horizontal platziert.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1. Schriftgroesse basiert jetzt auf Median-Zeilenhoehe statt
individueller Zellhoehe — keine Groessensprunge in Box-Bereichen
2. Sehr schmale Pixel-Cluster (< 0.5% Zellbreite) werden gefiltert,
damit Box-Rahmen nicht als Textposition erkannt werden
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Statt Side-by-Side wird der erkannte Text jetzt direkt ueber das
Originalbild gelegt. Textfarbe (rot/blau/schwarz) und Deckkraft
per Slider einstellbar fuer einfache visuelle Fehlersuche.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>