Critical Fix:
The previous implementation incorrectly calculated scale factors because
calculate_page_dimensions() was prioritizing source file dimensions over
OCR coordinate analysis, resulting in scale=1.0 when it should have been ~0.27.
Root Cause:
- PaddleOCR processes PDFs at high resolution (e.g., 2185x3500 pixels)
- OCR bbox coordinates are in this high-res space
- calculate_page_dimensions() was returning source PDF size (595x842) instead
- This caused scale_w=1.0, scale_h=1.0, placing all text out of bounds
Solution:
1. Rewrite calculate_page_dimensions() to:
- Accept full ocr_data instead of just text_regions
- Process both text_regions AND layout elements
- Handle polygon bbox format [[x,y], ...] correctly
- Infer OCR dimensions from max bbox coordinates FIRST
- Only fallback to source file dimensions if inference fails
2. Separate OCR dimensions from target PDF dimensions:
- ocr_width/height: Inferred from bbox (e.g., 2185x3280)
- target_width/height: From source file (e.g., 595x842)
- scale_w = target_width / ocr_width (e.g., 0.272)
- scale_h = target_height / ocr_height (e.g., 0.257)
3. Add PyPDF2 support:
- Extract dimensions from source PDF files
- Required for getting target PDF size
Changes:
- backend/app/services/pdf_generator_service.py:
- Fix calculate_page_dimensions() to infer from bbox first
- Add PyPDF2 support in get_original_page_size()
- Simplify scaling logic (removed ocr_dimensions dependency)
- Update all drawing calls to use target_height instead of page_height
- requirements.txt:
- Add PyPDF2>=3.0.0 for PDF dimension extraction
- backend/test_bbox_scaling.py:
- Add comprehensive test for high-res OCR → A4 PDF scenario
- Validates proper scale factor calculation (0.272 x 0.257)
Test Results:
✓ OCR dimensions correctly inferred: 2185.0 x 3280.0
✓ Target PDF dimensions extracted: 595.3 x 841.9
✓ Scale factors correct: X=0.272, Y=0.257
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Problem:
- OCR processes images at smaller resolutions but coordinates were being used directly on larger PDF canvases
- This caused all text/tables/images to be drawn at wrong scale in bottom-left corner
Solution:
- Track OCR image dimensions in JSON output (ocr_dimensions)
- Calculate proper scale factors: scale_w = pdf_width/ocr_width, scale_h = pdf_height/ocr_height
- Apply scaling to all coordinates before drawing on PDF canvas
- Support per-page scaling for multi-page PDFs
Changes:
1. ocr_service.py:
- Add OCR image dimensions capture using PIL
- Include ocr_dimensions in JSON output for both single images and PDFs
2. pdf_generator_service.py:
- Calculate scale factors from OCR dimensions vs target PDF dimensions
- Update all drawing methods (text, table, image) to accept and apply scale factors
- Apply scaling to bbox coordinates before coordinate transformation
3. test_pdf_scaling.py:
- Add test script to verify scaling works correctly
- Test with OCR at 500x700 scaled to PDF at 1000x1400 (2x scaling)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major Features:
- Add PDF generation service with Chinese font support
- Parse HTML tables from PP-StructureV3 and rebuild with ReportLab
- Extract table text for translation purposes
- Auto-filter text regions inside tables to avoid overlaps
Backend Changes:
1. pdf_generator_service.py (NEW)
- HTMLTableParser: Parse HTML tables to extract structure
- PDFGeneratorService: Generate layout-preserving PDFs
- Coordinate transformation: OCR (top-left) → PDF (bottom-left)
- Font size heuristics: 75% of bbox height with width checking
- Table reconstruction: Parse HTML → ReportLab Table
- Image embedding: Extract bbox from filenames
2. ocr_service.py
- Add _extract_table_text() for translation support
- Add output_dir parameter to save images to result directory
- Extract bbox from image filenames (img_in_table_box_x1_y1_x2_y2.jpg)
3. tasks.py
- Update process_task_ocr to use save_results() with PDF generation
- Fix download_pdf endpoint to use database-stored PDF paths
- Support on-demand PDF generation from JSON
4. config.py
- Add chinese_font_path configuration
- Add pdf_enable_bbox_debug flag
Frontend Changes:
1. PDFViewer.tsx (NEW)
- React PDF viewer with zoom and pagination
- Memoized file config to prevent unnecessary reloads
2. TaskDetailPage.tsx & ResultsPage.tsx
- Integrate PDF preview and download
3. main.tsx
- Configure PDF.js worker via CDN
4. vite.config.ts
- Add host: '0.0.0.0' for network access
- Use VITE_API_URL environment variable for backend proxy
Dependencies:
- reportlab: PDF generation library
- Noto Sans SC font: Chinese character support
🤖 Generated with Claude Code
https://claude.com/claude-code
Co-Authored-By: Claude <noreply@anthropic.com>