| import gradio as gr |
| from pathlib import Path |
| from datetime import datetime |
| from PIL import Image |
|
|
| from ocrpkg.core import ( |
| ocr_file, |
| run_ocr_on_image, |
| run_ocr_on_image_paddle, |
| save_json, |
| ) |
| from ocrpkg.pdf import pdf_to_images |
| from ocrpkg.schema import OCRBlock |
|
|
|
|
| def _make_preview_text(blocks): |
| pages = sorted({b.page for b in blocks}) |
| chunks = [] |
| for pg in pages: |
| page_text = "\n".join([b.text for b in blocks if b.page == pg]) |
| chunks.append(f"--- Page {pg} ---\n{page_text}") |
| return "\n\n".join(chunks) if chunks else "No text detected." |
|
|
|
|
| def _save_json_artifact(blocks, base_stem: str) -> str: |
| out_dir = Path("examples/output") |
| out_dir.mkdir(parents=True, exist_ok=True) |
| json_path = out_dir / f"{base_stem}.json" |
| save_json(blocks, json_path) |
| return str(json_path) |
|
|
|
|
| |
| def pdf_first_page_preview(file_obj): |
| if file_obj is None: |
| return None |
| p = Path(file_obj.name) |
| if p.suffix.lower() != ".pdf": |
| return None |
| try: |
| imgs = pdf_to_images(p, dpi=150) |
| return imgs[0] if imgs else None |
| except Exception: |
| return None |
|
|
|
|
| |
| def run_ocr_image(pil_image: Image.Image, langs: str, conf_thr: float, engine: str): |
| if pil_image is None: |
| return "No image uploaded", None |
|
|
| conf = float(conf_thr) |
| langs_list = [s.strip() for s in langs.split(",") if s.strip()] |
|
|
| if engine == "PaddleOCR": |
| primary_lang = langs_list[0] if langs_list else "en" |
| blocks = run_ocr_on_image_paddle(pil_image.convert("RGB"), lang=primary_lang, conf_threshold=conf, page=1) |
| else: |
| blocks = run_ocr_on_image(pil_image.convert("RGB"), langs=langs_list or ["en"], conf_threshold=conf, page=1) |
|
|
| preview_text = _make_preview_text(blocks) |
| base = f"image_{datetime.utcnow().strftime('%Y%m%d_%H%M%S')}" |
| json_path = _save_json_artifact(blocks, base) |
| return preview_text, json_path |
|
|
|
|
| def run_ocr_pdf(file_obj, langs: str, dpi: int, conf_thr: float, engine: str): |
| if file_obj is None: |
| return "No PDF uploaded", None |
| in_path = Path(file_obj.name) |
| if in_path.suffix.lower() != ".pdf": |
| return "Please upload a PDF file.", None |
|
|
| conf = float(conf_thr) |
| langs_list = [s.strip() for s in langs.split(",") if s.strip()] or ["en"] |
|
|
| if engine == "PaddleOCR": |
| |
| pages = pdf_to_images(in_path, dpi=int(dpi)) |
| all_blocks = [] |
| for i, img in enumerate(pages, start=1): |
| |
| blocks = run_ocr_on_image_paddle(img, lang=langs_list[0], conf_threshold=conf, page=i) |
| all_blocks.extend(blocks) |
| blocks = all_blocks |
| else: |
| |
| blocks = ocr_file(in_path, langs=langs_list, dpi=int(dpi), conf_threshold=conf) |
|
|
| preview_text = _make_preview_text(blocks) |
| json_path = _save_json_artifact(blocks, in_path.stem) |
| return preview_text, json_path |
|
|
|
|
| |
| with gr.Blocks() as demo: |
| gr.Markdown("# 📄 OCR & Document AI (EasyOCR + PaddleOCR)") |
| gr.Markdown( |
| "Images show a live preview in the upload area. PDFs show a first-page preview. " |
| "Choose **PaddleOCR** for higher quality (CPU), or **EasyOCR** as fallback. " |
| "Download structured JSON results." |
| ) |
|
|
| with gr.Tabs(): |
| |
| with gr.Tab("Image"): |
| with gr.Row(): |
| with gr.Column(): |
| img_in = gr.Image(type="pil", label="Upload image") |
| langs_img = gr.Textbox(value="en", label="Languages (comma-separated; EasyOCR uses this list)") |
| engine_img = gr.Dropdown(["PaddleOCR", "EasyOCR"], value="PaddleOCR", label="Engine") |
| conf_img = gr.Slider(0.0, 1.0, value=0.3, step=0.05, label="Confidence threshold") |
| btn_img = gr.Button("Run OCR on Image", variant="primary") |
| with gr.Column(): |
| txt_img = gr.Textbox(label="Recognized text (by page)", lines=16) |
| json_img = gr.File(label="Download JSON") |
|
|
| btn_img.click( |
| fn=run_ocr_image, |
| inputs=[img_in, langs_img, conf_img, engine_img], |
| outputs=[txt_img, json_img], |
| ) |
|
|
| |
| with gr.Tab("PDF"): |
| with gr.Row(): |
| with gr.Column(): |
| pdf_in = gr.File(label="Upload PDF", file_types=[".pdf"]) |
| pdf_preview = gr.Image(label="First Page Preview (auto)", interactive=False) |
| langs_pdf = gr.Textbox(value="en", label="Languages (comma-separated)") |
| engine_pdf = gr.Dropdown(["PaddleOCR", "EasyOCR"], value="PaddleOCR", label="Engine") |
| dpi_pdf = gr.Slider(100, 400, value=250, step=50, label="PDF render DPI") |
| conf_pdf = gr.Slider(0.0, 1.0, value=0.3, step=0.05, label="Confidence threshold") |
| btn_pdf = gr.Button("Run OCR on PDF", variant="primary") |
| with gr.Column(): |
| txt_pdf = gr.Textbox(label="Recognized text (by page)", lines=16) |
| json_pdf = gr.File(label="Download JSON") |
|
|
| |
| pdf_in.upload(fn=pdf_first_page_preview, inputs=pdf_in, outputs=pdf_preview) |
|
|
| btn_pdf.click( |
| fn=run_ocr_pdf, |
| inputs=[pdf_in, langs_pdf, dpi_pdf, conf_pdf, engine_pdf], |
| outputs=[txt_pdf, json_pdf], |
| ) |
|
|
| if __name__ == "__main__": |
| demo.launch() |