- Move all Python scripts to tools/ directory - Move documentation files to docs/ directory - Create exams/ and homework/ directories for future use - Remove temporary test file (page1_preview.png) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
123 lines
3.8 KiB
Python
123 lines
3.8 KiB
Python
#!/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)')
|