diff --git a/admin-lehrer/components/ocr-overlay/OverlayReconstruction.tsx b/admin-lehrer/components/ocr-overlay/OverlayReconstruction.tsx index 3161926..2b712f5 100644 --- a/admin-lehrer/components/ocr-overlay/OverlayReconstruction.tsx +++ b/admin-lehrer/components/ocr-overlay/OverlayReconstruction.tsx @@ -316,6 +316,14 @@ export function OverlayReconstruction({ sessionId, onNext }: OverlayReconstructi const imgH = imageNaturalSize?.h || 1 const containerH = reconWidth * (imgH / imgW) + // Compute median cell height (in px) for consistent font sizing + const medianCellHeightPx = useMemo(() => { + if (cells.length === 0) return 40 + const heights = cells.map(c => containerH * (c.bboxPct.h / 100)).sort((a, b) => a - b) + const mid = Math.floor(heights.length / 2) + return heights.length % 2 === 0 ? (heights[mid - 1] + heights[mid]) / 2 : heights[mid] + }, [cells, containerH]) + return (
{/* Toolbar */} @@ -460,13 +468,12 @@ export function OverlayReconstruction({ sessionId, onNext }: OverlayReconstructi const edited = isEdited(cell) const wordPos = cellWordPositions.get(cell.cellId) const bboxPct = cell.bboxPct - const cellHeightPx = containerH * (bboxPct.h / 100) const colorValue = textColor === 'black' ? '#1a1a1a' : textColor // Pixel-analysed: render word-groups at detected positions if (wordPos && wordPos.length > 0) { return wordPos.map((wp, i) => { - const autoFontPx = cellHeightPx * wp.fontRatio * fontScale + const autoFontPx = medianCellHeightPx * wp.fontRatio * fontScale const fs = Math.max(6, autoFontPx) if (wordPos.length > 1) { @@ -536,7 +543,7 @@ export function OverlayReconstruction({ sessionId, onNext }: OverlayReconstructi // Fallback: no pixel data — single input at cell bbox if (!cell.text) return null - const fontSize = Math.max(6, cellHeightPx * fontScale) + const fontSize = Math.max(6, medianCellHeightPx * fontScale) return (
(c.end - c.start + 1) > minClusterW) + if (clusters.length === 0) continue + if (rotation === 180) { clusters = clusters.map(c => ({ start: cw - 1 - c.end,