#!/usr/bin/env python3 """ Test scaling FROM CENTER (not from top). If center is aligned but extremes are off, we need to scale from center point. Also test with top margin offset. """ import json from pdf2image import convert_from_path from reportlab.pdfgen import canvas from reportlab.lib.utils import ImageReader from reportlab.lib.colors import red, blue from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont import tempfile import os # Font try: pdfmetrics.registerFont(TTFont('CF', 'C:/Windows/Fonts/msyh.ttc')) font = 'CF' except: font = 'Helvetica' # Load with open('Raw/DevelopChinese/OCR/听力Intro.json') as f: data = json.load(f) # Convert imgs = convert_from_path('Raw/DevelopChinese/PDF/听力Intro.pdf', dpi=300, first_page=1, last_page=1) img = imgs[0] w, h = img.size print(f'Image: {w}x{h}') # Find OCR coordinate range details = data['pages'][0]['details'] max_y_ocr = max(max(p[1] for p in d['bbox']) for d in details if d.get('bbox')) min_y_ocr = min(min(p[1] for p in d['bbox']) for d in details if d.get('bbox')) center_y_ocr = (min_y_ocr + max_y_ocr) / 2 print(f'OCR Y range: {min_y_ocr} to {max_y_ocr}, center: {center_y_ocr}') # Save image with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as tmp: img.save(tmp.name, 'PNG') tmp_path = tmp.name # Create PDF c = canvas.Canvas('test_CENTER_SCALING.pdf') # Detected top margin TOP_MARGIN = 199 # Test different Y scale factors (around 1.0) # Since center is good, we want to compress/expand from center test_scales = [0.90, 0.92, 0.94, 0.96, 0.98, 1.00, 1.02, 1.04, 1.06, 1.08, 1.10] for y_scale in test_scales: c.setPageSize((w, h)) c.drawImage(ImageReader(tmp_path), 0, 0, width=w, height=h) # Draw title c.setFont('Helvetica', 18) c.setFillColorRGB(1, 0, 0) c.drawString(50, h - 50, f'Y_SCALE: {y_scale:.2f} (from center) + margin: {TOP_MARGIN}px') # Draw boxes count = 0 for d in details: text = d.get('text', '').strip() if not text or count >= 30: continue bbox = d.get('bbox', []) if not bbox or len(bbox) != 4: continue xs = [p[0] for p in bbox] ys = [p[1] for p in bbox] x = min(xs) width = max(xs) - x y_ocr_max = max(ys) y_ocr_min = min(ys) # CRITICAL: Scale from center, not from top! # 1. Subtract margin offset y_ocr_max_adj = y_ocr_max - TOP_MARGIN y_ocr_min_adj = y_ocr_min - TOP_MARGIN center_y_adj = center_y_ocr - TOP_MARGIN # 2. Calculate distance from center dist_from_center_max = y_ocr_max_adj - center_y_adj dist_from_center_min = y_ocr_min_adj - center_y_adj # 3. Scale the distance from center scaled_max = center_y_adj + (dist_from_center_max * y_scale) scaled_min = center_y_adj + (dist_from_center_min * y_scale) # 4. Map to PDF coordinates (flip Y, scaled space height = max_y_ocr) scaled_space_height = max_y_ocr - TOP_MARGIN y_pdf = h - ((scaled_max / scaled_space_height) * h) height_pdf = ((scaled_max - scaled_min) / scaled_space_height) * h c.setStrokeColor(red) c.setLineWidth(0.5) c.rect(x, y_pdf, width, height_pdf, stroke=1, fill=0) font_size = max(1, height_pdf * 0.7) c.setFont(font, font_size) c.setFillColor(blue) c.drawString(x, y_pdf, text) count += 1 c.showPage() print(f'Page with Y scale {y_scale:.2f} done') c.save() os.unlink(tmp_path) print(f'\nCreated test_CENTER_SCALING.pdf with {len(test_scales)} pages') print('Find which Y_SCALE gives alignment at top, center AND bottom!') print(f'Scale < 1.0 = compress from center (bring extremes closer)') print(f'Scale > 1.0 = expand from center (push extremes further)')