Spaces:
Running
Running
| import gradio as gr | |
| from pdfminer.high_level import extract_text_to_fp | |
| from pdfminer.layout import LAParams | |
| from pdfminer.pdfpage import PDFPage | |
| from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter | |
| from pdfminer.converter import TextConverter | |
| import io | |
| def extract_text_from_pdf(pdf_file) -> str: | |
| """ | |
| Extrahiert Text aus einer PDF-Datei mit optimierten Parametern für | |
| komplexe Layouts (z. B. mehrspaltige Dokumente). | |
| """ | |
| if pdf_file is None: | |
| return "Keine Datei hochgeladen." | |
| # LAParams – optimal für komplexe / mehrspaltiges Layout | |
| laparams = LAParams( | |
| # Maximaler Abstand zwischen Zeichen innerhalb eines Worts | |
| word_margin=0.1, | |
| # Zeilenhöhen-Verhältnis, das zwei Zeilen als zusammengehörig betrachtet | |
| line_margin=0.3, | |
| # Verhältnis von Zeichenbreite zu Abstand, um Wortgrenzen zu bestimmen | |
| char_margin=1.5, | |
| # Verhältnis Boxbreite zu Seitenbreite – Schwelle für neue Spalte | |
| boxes_flow=0.5, # 0 = rein horizontal, 1 = rein vertikal, 0.5 = ausgewogen | |
| # Nur horizontalen Text berücksichtigen (False = auch rotiert) | |
| detect_vertical=False, | |
| # Alle Textboxen behalten, auch ohne explizite Linie | |
| all_texts=False, | |
| ) | |
| rsrcmgr = PDFResourceManager() | |
| output = io.StringIO() | |
| with open(pdf_file, "rb") as f: | |
| converter = TextConverter(rsrcmgr, output, laparams=laparams) | |
| interpreter = PDFPageInterpreter(rsrcmgr, converter) | |
| pages = list(PDFPage.get_pages(f, check_extractable=True)) | |
| total_pages = len(pages) | |
| for page in pages: | |
| interpreter.process_page(page) | |
| converter.close() | |
| text = output.getvalue() | |
| output.close() | |
| if not text.strip(): | |
| return "⚠️ Kein extrahierbarer Text gefunden (möglicherweise ein gescanntes PDF)." | |
| return f"📄 {total_pages} Seite(n) verarbeitet\n\n{text}" | |
| # ── Gradio UI ────────────────────────────────────────────────────────────────── | |
| with gr.Blocks(title="PDF Textextraktion") as demo: | |
| gr.Markdown( | |
| """ | |
| # 📄 PDF Textextraktion | |
| Lädt eine PDF-Datei hoch und extrahiert den Text mit **pdfminer.six**, | |
| optimiert für **komplexe Layouts** (Mehrspaltigkeit, Tabellen, gemischter Fluss). | |
| """ | |
| ) | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| pdf_input = gr.File( | |
| label="PDF hochladen", | |
| file_types=[".pdf"], | |
| type="filepath", | |
| ) | |
| extract_btn = gr.Button("Text extrahieren", variant="primary") | |
| with gr.Column(scale=2): | |
| text_output = gr.Textbox( | |
| label="Extrahierter Text", | |
| lines=30, | |
| max_lines=100, | |
| show_copy_button=True, | |
| placeholder="Der extrahierte Text erscheint hier…", | |
| ) | |
| extract_btn.click( | |
| fn=extract_text_from_pdf, | |
| inputs=pdf_input, | |
| outputs=text_output, | |
| ) | |
| gr.Markdown( | |
| """ | |
| --- | |
| **Parametererklärung (LAParams):** | |
| | Parameter | Wert | Bedeutung | | |
| |-----------|------|-----------| | |
| | `char_margin` | 1.5 | Zeichenabstand für Worterkennung | | |
| | `word_margin` | 0.1 | Wortabstand innerhalb einer Zeile | | |
| | `line_margin` | 0.3 | Zeilenabstand für Absatzerkennung | | |
| | `boxes_flow` | 0.5 | Ausgewogene Spalten- & Zeilenerkennung | | |
| | `detect_vertical` | False | Nur horizontalen Text verarbeiten | | |
| """ | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() |