#182 Screenshot – OCR – Automatisch umblättern, Stunden gespart

Worum geht es in diesem Artikel?

Wir erleben das KI Systeme immer besser und schneller für alle mögliche Anwendungsfälle und spezialisierten Code schreiben kann. Die Fehlerquoto wird immer geringer.

Stellen Sie sich vor, Sie möchten Inhalte aus einem Digitalen-Buch (wo man keine Quellen hat) extrahieren – sei es, um die Texte für ein Forschungsprojekt weiterzuverarbeiten, bestimmte Passagen zu zitieren oder eine umfassende Analyse in einer Datenbank durchzuführen. Der klassische Weg wäre mühevoll: jede Seite einzeln aufrufen, manuell Screenshots machen, Bilder per Hand zuschneiden, anschließend den Text über eine OCR-Software erkennen lassen, die Daten sammeln und für die Weiterverarbeitung aufbereiten. Das kostet nicht nur viel Zeit, sondern birgt auch ein hohes Fehlerrisiko, weil jeder Schritt manuell erledigt werden muss.

Genau an diesem Punkt kommt das automatisierte Python Skript ins Spiel das ich dazu erstellt habe. Ich korrigiere mich Claude hat es in 30 Minuten gemacht.

Der Hintergrund: ich wollte mit dem Buch von Gary VAYNERCHUK arbeiten und den Text auf Deutsch lesen (bin ich ungefähr 10 mal schneller). Also den Text auf Deutsch übersetzen und in eine Vector Datenbank bringen zum erarbeiten und erklären.

Dazu muss ich den Text des Buches haben, den in einer PDF zusammenfassen und auf Deutsch übersetzen.



Vielleicht auch für folgende Aufgaben geeignet.

  1. Studierende und Forschende, die für ihre Abschlussarbeiten, Dissertationen oder Studienprojekte große Textmengen schnell digitalisieren und durchsuchen wollen.
  2. Buchliebhaber mit umfangreichen E-Book-Bibliotheken, die bestimmte Passagen oder Bilder für persönliche Projekte oder zum Zitieren bequem extrahieren möchten.
  3. Entwickler*innen und Datenanalysten, die NLP-Modelle (Natural Language Processing) trainieren oder Daten in Vektordatenbanken einspeisen möchten.
  4. Alle, die viel mit E-Books und Dokumenten arbeiten, z.B. im beruflichen Kontext, um Textstellen schnell bereitzustellen oder archivieren zu können.

Welche Probleme löst das Skript?

  • Zeitaufwand reduzieren: Statt jede Seite einzeln zu fotografieren, erkennt das Skript selbstständig, wann eine Seite fertig erfasst ist, macht Screenshots und blättert automatisch um.
  • Fehleranfälligkeit minimieren: Wo manuell schnell vertippt oder vergessen wird, eine Seite zu fotografieren, sorgt die Automatisierung für eine konsistente, lückenlose Erfassung.
  • Direkte Texterkennung (OCR): Sie müssen keine zusätzliche Software starten oder jeden Screenshot manuell bearbeiten. Die enthaltenen Texte werden automatisch erkannt und in einer Markdown-Datei gespeichert.
  • Extraktion von Bildern: Falls das Buch Grafiken, Illustrationen oder Diagramme enthält, werden diese erkannt und separat abgelegt – Sie müssen diese also nicht selbst zuschneiden.
  • Aufbereitung für weitere Verarbeitung: Ob Sie die Daten in eine Vektordatenbank importieren, für KI-Modelle aufbereiten oder in ein Textanalyse-Tool einspeisen wollen – Sie erhalten sofort maschinenlesbare Daten.

Welche möglichen Schwierigkeiten können auftreten?

  1. Tesseract-Installation: Damit die OCR funktioniert, muss Tesseract korrekt installiert sein. Wenn Tesseract nicht gefunden wird oder die Sprache fehlt, kann es zu Fehlermeldungen kommen.
  2. Betriebssystemabhängigkeit: Das Skript nutzt AppleScript-Aufrufe, um den Namen der APP die umgeblättert werden sollzu aktivieren. Auf Windows oder Linux wäre hier eine Anpassung nötig (z.B. Fensterfokus über andere Automatisierungs-Tools).
  3. UI-Positionierung: Das Skript verlässt sich auf die vorhandene Bildschirmkonfiguration. Ein ungewohntes Fensterlayout oder mehrfach angeschlossene Monitore können dazu führen, dass der Namen der APP die umgeblättert werden soll nicht an der erwarteten Position erscheint.
  4. OCR-Genauigkeit: Die Qualität der erkannten Texte hängt von der Buchseite, Schriftart, Hintergrundfarbe und Beleuchtung (bei farbigen Scans) ab. Auch sehr kleine oder verschobene Schrift kann Probleme verursachen.
  5. Leistungsanforderungen: Das Anfertigen von Screenshots und parallele OCR-Auswertung kann auf schwächeren Rechnern sehr ressourcenintensiv sein. In diesen Fällen sollte man das Skript mit einer geringeren Seitenanzahl starten oder längere Pausen einplanen.

Warum automatisch erstellte Skripte

Die hier gezeigte Automatisierung ist ein perfektes Beispiel, wie KI-gestützte Tools (wie Chatgpt) den Workflow vereinfachen können. Statt jedes Mal selbst Script-Strukturen zu erdenken und zu programmieren, lassen sich:

  • Wiederkehrende Muster (z.B. Screenshots erstellen, OCR, Speicherung in Markdown) schnell neu kombinieren oder anpassen.
  • Fehlerquellen reduzieren, da die AI-gestützte Code-Generierung bereits gängige Best Practices und Lösungsansätze verinnerlicht hat.
  • Skripte flexibel erweitern, z.B. für zusätzliche Dateiformate (PDF, DOCX-Export) oder Sprachpakete bei der OCR.

All dies spart kostbare Zeit, verbessert die Datenqualität und sorgt dafür, dass Sie sich stärker auf den eigentlichen Inhalt des Buchs konzentrieren können, statt auf die manuelle Extraktion.

Hier das Script, es hat noch einen Fehler, die Markdown Bilder werden nur relativ eingesetzt. Sonst funktioniert alles. Für den Namen der APP die umgeblättert werden soll muss das Programm eingesetzt werden wo screenshots gemacht werden sollen.

import os
import time
import pyautogui
from datetime import datetime
from pathlib import Path
import subprocess
from PIL import Image
import pytesseract
import re
import cv2
import numpy as np

def activate_Namen der APP die umgeblättert werden soll():
    subprocess.run(['osascript', '-e', 'tell application "Namen der APP die umgeblättert werden soll" to activate'])
    time.sleep(0.2)

def enter_fullscreen():
    pyautogui.press('f11')
    time.sleep(0.3)

def exit_fullscreen():
    pyautogui.press('esc')
    time.sleep(0.2)

def detect_images_in_scan(image_path, output_dir):
    """Erkennt und extrahiert Bilder aus einem Scan"""
    # Bild einlesen
    img = cv2.imread(image_path)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # Adaptive Schwellenwert-Segmentierung
    thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, 
                                 cv2.THRESH_BINARY_INV, 11, 2)
    
    # Konturen finden
    contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
    # Extrahierte Bilder speichern
    extracted_images = []
    min_area = img.shape[0] * img.shape[1] * 0.01  # Mindestens 1% der Seitengröße
    
    for i, contour in enumerate(contours):
        area = cv2.contourArea(contour)
        if area > min_area:
            x, y, w, h = cv2.boundingRect(contour)
            roi = img[y:y+h, x:x+w]
            
            # Speichere das extrahierte Bild
            image_filename = f"extracted_image_{i}.png"
            image_path = os.path.join(output_dir, image_filename)
            cv2.imwrite(image_path, roi)
            extracted_images.append(image_path)
    
    return extracted_images

def clean_text(text):
    """Bereinigt den OCR-Text"""
    text = re.sub(r'\s+', ' ', text)
    text = re.sub(r'-\s+', '', text)
    text = text.strip()
    return text

def scan_image(image_path):
    """OCR auf einem Bild durchführen"""
    try:
        text = pytesseract.image_to_string(Image.open(image_path), lang='deu')
        return clean_text(text)
    except Exception as e:
        print(f"Fehler bei OCR von {image_path}: {e}")
        return ""

def append_to_markdown(md_path, page_number, image_path, text, extracted_images):
    """Fügt eine neue Seite zur Markdown-Datei hinzu"""
    with open(md_path, 'a', encoding='utf-8') as f:
        f.write(f"\n\n## Seite {page_number}\n\n")
        f.write(f"![Seite {page_number}]({os.path.relpath(image_path, os.path.dirname(md_path))})\n\n")
        f.write(text)
        
        # Füge extrahierte Bilder hinzu
        if extracted_images:
            f.write("\n\n### Extrahierte Bilder\n\n")
            for img_path in extracted_images:
                rel_path = os.path.relpath(img_path, os.path.dirname(md_path))
                f.write(f"![Extrahiertes Bild]({rel_path})\n\n")
        
        f.write("\n\n---\n")

def images_are_similar(img1_path, img2_path):
    """Vergleicht zwei Bilder und prüft ob sie fast identisch sind"""
    if not os.path.exists(img1_path) or not os.path.exists(img2_path):
        return False
        
    with Image.open(img1_path) as img1, Image.open(img2_path) as img2:
        if img1.size != img2.size:
            return False
            
        pairs = zip(img1.getdata(), img2.getdata())
        dif = sum(abs(c1 - c2) for p1, p2 in pairs for c1, c2 in zip(p1, p2))
        ncomponents = img1.size[0] * img1.size[1] * 3
        return (dif / 255.0 * 100) / ncomponents < 2.0

def take_Namen der APP die umgeblättert werden soll_screenshots():
    folder_name = input("Wie soll der Ordner heißen? ")
    num_screenshots = int(input("Wie viele Screenshots sollen gemacht werden? "))
    speed = input("Schneller Modus? (j/n): ").lower() == 'j'
    
    page_turn_delay = 0.2 if speed else 0.8
    check_window_interval = 10 if speed else 1
    
    print("\nWichtige Steuerung:")
    print("- Maus in eine Bildschirmecke bewegen zum Abbrechen")
    print("- Programm erkennt automatisch das Buchende")
    if speed:
        print("- TURBO-MODUS AKTIV\n")
    
    desktop = str(Path.home() / "Desktop")
    folder_path = os.path.join(desktop, folder_name)
    extracted_images_path = os.path.join(folder_path, "extracted_images")
    os.makedirs(folder_path, exist_ok=True)
    os.makedirs(extracted_images_path, exist_ok=True)
    
    md_path = os.path.join(folder_path, "buch_text.md")
    with open(md_path, 'w', encoding='utf-8') as f:
        f.write(f"# Namen der APP die umgeblättert werden soll Buch Export\n\nErstellt am: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
    
    print("Namen der APP die umgeblättert werden soll wird aktiviert und in Vollbild geschaltet...")
    activate_Namen der APP die umgeblättert werden soll()
    enter_fullscreen()
    
    time.sleep(1)
    
    last_pages = []
    required_identical_pages = 4
    check_last_n_pages = 3
    
    start_time = time.time()
    
    for i in range(num_screenshots):
        current_file = os.path.join(folder_path, f"Screenshot_{i+1}.png")
        
        if not speed or i % check_window_interval == 0:
            activate_Namen der APP die umgeblättert werden soll()
        
        # Screenshot machen
        screenshot = pyautogui.screenshot()
        screenshot.save(current_file)
        
        # Bilder aus dem Scan extrahieren
        print(f"Suche nach Bildern in Seite {i+1}...")
        extracted_images = detect_images_in_scan(current_file, extracted_images_path)
        if extracted_images:
            print(f"  {len(extracted_images)} Bilder gefunden und extrahiert")
        
        # OCR durchführen
        print(f"Führe OCR für Seite {i+1} durch...")
        text = scan_image(current_file)
        append_to_markdown(md_path, i+1, current_file, text, extracted_images)
        
        # Fortschrittsanzeige
        elapsed_time = time.time() - start_time
        pages_per_second = (i + 1) / elapsed_time if elapsed_time > 0 else 0
        estimated_total = num_screenshots / pages_per_second if pages_per_second > 0 else 0
        remaining_time = estimated_total - elapsed_time
        
        print(f"Screenshot {i+1}/{num_screenshots} erstellt und verarbeitet "
              f"(~{remaining_time:.1f}s verbleibend, "
              f"{pages_per_second:.1f} Seiten/Sekunde)")
        
        # Prüfe die letzten Seiten auf Änderungen
        if i > 0:
            last_pages.append(current_file)
            if len(last_pages) > check_last_n_pages:
                last_pages.pop(0)
            
            identical_pages = 0
            for j in range(len(last_pages)-1):
                if images_are_similar(last_pages[j], last_pages[j+1]):
                    identical_pages += 1
            
            if identical_pages >= required_identical_pages:
                print(f"\nLetzte {required_identical_pages} Seiten waren identisch - vermutlich Buchende erreicht.")
                user_continue = input("Trotzdem fortfahren? (j/n): ").lower() == 'j'
                if not user_continue:
                    break
                else:
                    last_pages = []
            
        # Nächste Seite
        if i < num_screenshots - 1:
            pyautogui.press('right')
            time.sleep(page_turn_delay)
    
    # Aufräumen
    exit_fullscreen()
    
    total_time = time.time() - start_time
    print(f"\nFertig! {i+1} Screenshots in {total_time:.1f} Sekunden "
          f"({(i+1)/total_time:.1f} Seiten/Sekunde)")
    print(f"Alle Bilder wurden im Ordner {folder_path} gespeichert")
    print(f"Extrahierte Bilder befinden sich in {extracted_images_path}")
    print(f"Der extrahierte Text wurde in {md_path} gespeichert")

if __name__ == "__main__":
    pyautogui.FAILSAFE = True
    try:
        take_Namen der APP die umgeblättert werden soll_screenshots()
    except KeyboardInterrupt:
        print("\nProgramm wurde manuell beendet.")
        exit_fullscreen()
    except Exception as e:
        print(f"\nFehler aufgetreten: {e}")
        exit_fullscreen()

Teile diesen Artikel

Ähnliche Beiträge