diff --git a/AdobeFlatten/10 FlattenAdobe.py b/AdobeFlatten/10 FlattenAdobe.py index bbef786..8dc86c2 100644 --- a/AdobeFlatten/10 FlattenAdobe.py +++ b/AdobeFlatten/10 FlattenAdobe.py @@ -1,7 +1,7 @@ import fitz from pathlib import Path -BASE_DIR = Path(r"z:\Dropbox\Ordinace\Dokumentace_ke_zpracování\AdobeFlattenStamp") +BASE_DIR = Path(r"u:\Dropbox\Ordinace\Dokumentace_ke_zpracování\AdobeFlattenStamp") def flatten_pdf_rasterize(input_pdf: Path): print(f"Processing: {input_pdf.name}") diff --git a/AdobeFlatten/20 FlattenAdobe.py b/AdobeFlatten/20 FlattenAdobe.py new file mode 100644 index 0000000..7db2f8b --- /dev/null +++ b/AdobeFlatten/20 FlattenAdobe.py @@ -0,0 +1,74 @@ +import fitz +from pathlib import Path +import platform +import sys +import tempfile +import os + +HOSTNAME = platform.node().upper() + +if HOSTNAME in {"SESTRA", "POHODA"}: + DROPBOX_DRIVE = Path(r"Z:\\") +elif HOSTNAME == "Z230": + DROPBOX_DRIVE = Path(r"U:\\") +else: + print(f"❌ Unknown computer name: {HOSTNAME}") + sys.exit(1) + +BASE_DIR = ( + DROPBOX_DRIVE + / "Dropbox" + / "Ordinace" + / "Dokumentace_ke_zpracování" + / "AdobeFlattenStamp" +) + +def flatten_pdf_rasterize_overwrite(input_pdf: Path): + print(f"Processing: {input_pdf.name}") + + doc = fitz.open(input_pdf) + new_doc = fitz.open() + + for page in doc: + pix = page.get_pixmap(dpi=400) + new_page = new_doc.new_page( + width=page.rect.width, + height=page.rect.height + ) + new_page.insert_image(new_page.rect, pixmap=pix) + + # safe overwrite + with tempfile.NamedTemporaryFile( + suffix=".pdf", + delete=False, + dir=input_pdf.parent + ) as tmp: + tmp_path = Path(tmp.name) + + new_doc.save(tmp_path, deflate=True) + new_doc.close() + doc.close() + + os.replace(tmp_path, input_pdf) + print(f" ✔ Overwritten: {input_pdf.name}") + +def main(): + print(f"🖥 Running on: {HOSTNAME}") + print(f"📁 Base directory: {BASE_DIR}") + + if not BASE_DIR.exists(): + print("❌ Base directory does not exist!") + sys.exit(1) + + pdfs = list(BASE_DIR.glob("*.pdf")) + if not pdfs: + print("No PDF files found.") + return + + for pdf in pdfs: + flatten_pdf_rasterize_overwrite(pdf) + + print("\n✅ All files processed and originals overwritten.") + +if __name__ == "__main__": + main() diff --git a/MakeSmallerPDF/06 OCR Tesseract.py b/MakeSmallerPDF/06 OCR Tesseract.py new file mode 100644 index 0000000..80695e1 --- /dev/null +++ b/MakeSmallerPDF/06 OCR Tesseract.py @@ -0,0 +1,145 @@ +import fitz # PyMuPDF +import pytesseract +from PIL import Image +import io +import os +import re + +# --- NASTAVENÍ --- +INPUT_FOLDER = r'u:\Dropbox\Ordinace\Dokumentace_ke_zpracování\AdobeMakeSmaller' +OUTPUT_FOLDER = os.path.join(INPUT_FOLDER, '_HOTOVO_ULTIMATE') + +# Cesta k Tesseractu +PATH_TO_TESSERACT = r'C:\Program Files\Tesseract-OCR\tesseract.exe' + +# 1. Jak moc "ošklivý" (malý) má být viditelný obrázek? +VISUAL_DPI = 150 +VISUAL_THRESHOLD = 150 + +# 2. Jak kvalitní má být předloha pro čtení (OCR)? +OCR_DPI = 300 + + +def setup_tesseract(): + if not os.path.exists(PATH_TO_TESSERACT): + print(f"CHYBA: Tesseract nenalezen na: {PATH_TO_TESSERACT}") + return False + pytesseract.pytesseract.tesseract_cmd = PATH_TO_TESSERACT + return True + + +def get_rc_from_text(text): + """Najde RČ v textu a vrátí ho bez lomítka.""" + # Hledá formát: 6 čísel, volitelně lomítko/mezera, 3-4 čísla + matches = re.findall(r'\b(\d{6})\s*[\/]?\s*(\d{3,4})\b', text) + for head, tail in matches: + full_rc = f"{head}{tail}" + # Základní kontrola délky a čísel + if len(full_rc) in [9, 10] and full_rc.isdigit(): + return full_rc + return None + + +def process_ultimate_method(): + if not setup_tesseract(): + return + + if not os.path.exists(OUTPUT_FOLDER): + os.makedirs(OUTPUT_FOLDER) + + files = [f for f in os.listdir(INPUT_FOLDER) if f.lower().endswith('.pdf')] + print(f"Startuji 'ULTIMATE' zpracování {len(files)} souborů.") + print("-" * 70) + + for filename in files: + input_path = os.path.join(INPUT_FOLDER, filename) + + try: + print(f"Zpracovávám: {filename} ...") + + doc_src = fitz.open(input_path) + final_doc = fitz.open() + + detected_rc = None + + for page_num, page in enumerate(doc_src): + # --- KROK A: OCR (Vysoká kvalita pro čtení) --- + # 1. Vyrenderujeme kvalitní obrázek pro Tesseract + mat_ocr = fitz.Matrix(OCR_DPI / 72, OCR_DPI / 72) + pix_ocr = page.get_pixmap(matrix=mat_ocr, colorspace=fitz.csGRAY) + img_ocr = Image.frombytes("L", [pix_ocr.width, pix_ocr.height], pix_ocr.samples) + + # 2. Tesseract vytvoří PDF stránku (Text + Velký obrázek) + pdf_bytes = pytesseract.image_to_pdf_or_hocr(img_ocr, extension='pdf', lang='ces') + + # 3. Otevřeme tuto stránku v paměti + ocr_page_doc = fitz.open("pdf", pdf_bytes) + ocr_page = ocr_page_doc[0] + + # Přečteme text pro hledání RČ + if not detected_rc: + text_content = ocr_page.get_text() + detected_rc = get_rc_from_text(text_content) + + # --- KROK B: Visual (Nízká kvalita pro oči/úsporu) --- + # 1. Vyrenderujeme malý obrázek + mat_vis = fitz.Matrix(VISUAL_DPI / 72, VISUAL_DPI / 72) + pix_vis = page.get_pixmap(matrix=mat_vis, colorspace=fitz.csGRAY) + img_vis = Image.frombytes("L", [pix_vis.width, pix_vis.height], pix_vis.samples) + + # 2. Binarizace (Threshold) + img_vis_bw = img_vis.point(lambda x: 255 if x > VISUAL_THRESHOLD else 0, mode='1') + + # 3. Uložíme do bufferu + buffer_vis = io.BytesIO() + img_vis_bw.save(buffer_vis, format="PNG", optimize=True) + + # --- KROK C: Výměna (The Switch) --- + # 1. Smažeme velký obrázek z Tesseract stránky (text zůstane) + images = ocr_page.get_images() + if images: + xref = images[0][0] + ocr_page.delete_image(xref) + + # 2. Vložíme náš malý obrázek + # Použijeme rect (rozměry) stránky, aby obrázek seděl přesně na celou stranu + ocr_page.insert_image(ocr_page.rect, stream=buffer_vis.getvalue(), keep_proportion=True) + + # 3. Vložíme upravenou stránku do finálního PDF + final_doc.insert_pdf(ocr_page_doc) + + # --- KROK D: Uložení --- + if detected_rc: + new_filename = f"{detected_rc}.pdf" + print(f" -> Nalezeno RČ: {detected_rc}") + else: + new_filename = f"{os.path.splitext(filename)[0]}_ocr.pdf" + print(f" -> RČ nenalezeno.") + + # Řešení duplicit (pokud soubor už existuje) + counter = 1 + base_name_check = os.path.splitext(new_filename)[0] + while os.path.exists(os.path.join(OUTPUT_FOLDER, new_filename)): + new_filename = f"{base_name_check}_{counter}.pdf" + counter += 1 + + output_path = os.path.join(OUTPUT_FOLDER, new_filename) + + # Uložení s kompresí + final_doc.save(output_path, garbage=4, deflate=True) + final_doc.close() + doc_src.close() + + # Výpis velikosti + size_kb = os.path.getsize(output_path) / 1024 + print(f" -> Uloženo: {new_filename} ({size_kb:.1f} kB)") + print("-" * 40) + + except Exception as e: + print(f"CHYBA u {filename}: {e}") + + print("\nHOTOVO.") + + +if __name__ == "__main__": + process_ultimate_method() \ No newline at end of file diff --git a/MakeSmallerPDF/07 OCR tesseract lepší.py b/MakeSmallerPDF/07 OCR tesseract lepší.py new file mode 100644 index 0000000..725c27e --- /dev/null +++ b/MakeSmallerPDF/07 OCR tesseract lepší.py @@ -0,0 +1,205 @@ +import fitz # PyMuPDF +import pytesseract +from PIL import Image +import io +import os +import re +import fdb # Firebird database library + +# ========================================== +# KONFIGURACE +# ========================================== + +# 1. Cesty k souborům +INPUT_FOLDER = r'u:\Dropbox\Ordinace\Dokumentace_ke_zpracování\AdobeMakeSmaller' +OUTPUT_FOLDER = os.path.join(INPUT_FOLDER, '_HOTOVO_MEDICUS') + +# 2. Tesseract OCR +PATH_TO_TESSERACT = r'C:\Program Files\Tesseract-OCR\tesseract.exe' + +# 3. Kvalita výstupu (Ultimate metoda) +VISUAL_DPI = 150 # Pro zobrazení (malé) +VISUAL_THRESHOLD = 150 # Práh černé +OCR_DPI = 300 # Pro čtení (velké) + +# 4. Databáze MEDICUS (Firebird) +DB_CONFIG = { + 'host': "192.168.1.4", + 'port': 3050, + 'database': r"z:\Medicus 3\data\MEDICUS.FDB", + 'user': "SYSDBA", + 'password': "masterkey", + 'charset': "WIN1250" # Čeština ve Windows +} + + +# ========================================== +# FUNKCE +# ========================================== + +def setup_tesseract(): + if not os.path.exists(PATH_TO_TESSERACT): + print(f"CHYBA: Tesseract nenalezen na: {PATH_TO_TESSERACT}") + return False + pytesseract.pytesseract.tesseract_cmd = PATH_TO_TESSERACT + return True + + +def get_rc_candidates(text): + """Vrátí seznam RČ nalezených v textu, očistěných od mezer a lomítek.""" + candidates = set() + # Regex bere i mezery: 75 05 12 / 1234 + pattern = r'\b\d{2}\s*\d{2}\s*\d{2}\s*[\/]?\s*\d{3,4}\b' + matches = re.findall(pattern, text) + + for match in matches: + # Odstraníme vše kromě čísel -> vznikne čisté RČ pro DB + clean = re.sub(r'[^\d]', '', match) + if len(clean) in [9, 10]: + candidates.add(clean) + return list(candidates) + + +def get_patient_from_db(rc_clean): + """ + Vrátí (True, "Prijmeni, Jmeno") pokud najde RČ v tabulce KAR. + """ + con = None + try: + con = fdb.connect(**DB_CONFIG) + cur = con.cursor() + + # Medicus má RČ bez lomítka, takže se ptáme rovnou + sql = "SELECT prijmeni, jmeno FROM kar WHERE rodcis = ?" + cur.execute(sql, (rc_clean,)) + row = cur.fetchone() + + if row: + # row[0] = Prijmeni, row[1] = Jmeno + # .strip() je nutný, databáze vrací mezery na konci (CHAR field) + prijmeni = str(row[0]).strip() + jmeno = str(row[1]).strip() + + formatted_name = f"{prijmeni}, {jmeno}" + return True, formatted_name + else: + return False, None + + except Exception as e: + print(f" [DB ERROR] {e}") + return False, None + finally: + if con: + con.close() + + +def process_medicus_final(): + if not setup_tesseract(): + return + + if not os.path.exists(OUTPUT_FOLDER): + os.makedirs(OUTPUT_FOLDER) + + files = [f for f in os.listdir(INPUT_FOLDER) if f.lower().endswith('.pdf')] + print(f"Startuji zpracování {len(files)} souborů.") + print(f"Výstupní formát: 'RC Prijmeni, Jmeno.pdf'") + print("-" * 70) + + for filename in files: + input_path = os.path.join(INPUT_FOLDER, filename) + + try: + print(f"Zpracovávám: {filename}") + + doc_src = fitz.open(input_path) + final_doc = fitz.open() + + found_rc = None + found_name = None + + # --- 1. PRŮCHOD STRÁNKAMI --- + for page_num, page in enumerate(doc_src): + + # A) PŘÍPRAVA OCR VRSTVY (High Res) + mat_ocr = fitz.Matrix(OCR_DPI / 72, OCR_DPI / 72) + pix_ocr = page.get_pixmap(matrix=mat_ocr, colorspace=fitz.csGRAY) + img_ocr = Image.frombytes("L", [pix_ocr.width, pix_ocr.height], pix_ocr.samples) + + # Tesseract vytvoří PDF stránku + pdf_bytes = pytesseract.image_to_pdf_or_hocr(img_ocr, extension='pdf', lang='ces') + ocr_page_doc = fitz.open("pdf", pdf_bytes) + ocr_page = ocr_page_doc[0] + + # B) HLEDÁNÍ PACIENTA (pokud ještě nemáme) + if not found_rc: + text = ocr_page.get_text() + candidates = get_rc_candidates(text) + + for cand in candidates: + print(f" -> Ověřuji v DB: {cand} ...", end=" ") + exists, name_str = get_patient_from_db(cand) + + if exists: + print(f"NALEZEN: {name_str}") + found_rc = cand + found_name = name_str + break # Máme ho! + else: + print("Nenalezen.") + + # C) PŘÍPRAVA VIZUÁLNÍ VRSTVY (Low Res - Zmenšení) + mat_vis = fitz.Matrix(VISUAL_DPI / 72, VISUAL_DPI / 72) + pix_vis = page.get_pixmap(matrix=mat_vis, colorspace=fitz.csGRAY) + img_vis = Image.frombytes("L", [pix_vis.width, pix_vis.height], pix_vis.samples) + # Threshold + img_vis_bw = img_vis.point(lambda x: 255 if x > VISUAL_THRESHOLD else 0, mode='1') + + buffer_vis = io.BytesIO() + img_vis_bw.save(buffer_vis, format="PNG", optimize=True) + + # D) PROHOZENÍ OBRÁZKŮ (Ultimate trick) + images = ocr_page.get_images() + if images: + xref = images[0][0] + ocr_page.delete_image(xref) # Smaže velký + + # Vloží malý + ocr_page.insert_image(ocr_page.rect, stream=buffer_vis.getvalue(), keep_proportion=True) + + # Přidá stránku do finálního PDF + final_doc.insert_pdf(ocr_page_doc) + + # --- 2. ULOŽENÍ SOUBORU --- + if found_rc and found_name: + # Formát: 1234567890 NOVAK, JAN.pdf + # Odstraníme případné nepovolené znaky ve jméně (pro jistotu) + safe_name = re.sub(r'[\\/*?:"<>|]', "", found_name) + new_filename = f"{found_rc} {safe_name}.pdf" + else: + new_filename = f"{os.path.splitext(filename)[0]}_neovereno.pdf" + + # Řešení konfliktů (kdyby soubor už existoval) + counter = 1 + base_name = os.path.splitext(new_filename)[0] + while os.path.exists(os.path.join(OUTPUT_FOLDER, new_filename)): + new_filename = f"{base_name}_{counter}.pdf" + counter += 1 + + output_path = os.path.join(OUTPUT_FOLDER, new_filename) + + final_doc.save(output_path, garbage=4, deflate=True) + final_doc.close() + doc_src.close() + + size_kb = os.path.getsize(output_path) / 1024 + print(f" -> Uloženo: {new_filename} ({size_kb:.1f} kB)") + print("-" * 70) + + except Exception as e: + print(f"CHYBA: {e}") + + print("\nHOTOVO.") + + +if __name__ == "__main__": + process_medicus_final() \ No newline at end of file diff --git a/MakeSmallerPDF/2 MakeSmaller.py b/MakeSmallerPDF/2 MakeSmaller.py new file mode 100644 index 0000000..b57751b --- /dev/null +++ b/MakeSmallerPDF/2 MakeSmaller.py @@ -0,0 +1,66 @@ +import fitz # PyMuPDF +import os + + +def compress_and_grayscale_pdf(input_path, quality=60, dpi=150): + """ + input_path: Cesta k souboru + quality: Kvalita JPG komprese (1-100). 60 je dobrý kompromis pro čitelnost a velikost. + dpi: Rozlišení. 150 DPI stačí pro čtení na monitoru/běžný tisk. Pro menší velikost zkuste 96 nebo 72. + """ + + # Kontrola existence souboru + if not os.path.exists(input_path): + print(f"Chyba: Soubor nebyl nalezen: {input_path}") + return + + try: + # Otevření zdrojového PDF + doc = fitz.open(input_path) + new_doc = fitz.open() # Vytvoření nového prázdného PDF + + print(f"Zpracovávám: {os.path.basename(input_path)}") + print(f"Původní velikost: {os.path.getsize(input_path) / 1024:.2f} KB") + + for page_num, page in enumerate(doc): + # Nastavení matice pro změnu rozlišení (DPI) + # Standardní PDF má 72 DPI. Zoom = požadované DPI / 72 + zoom = dpi / 72 + matrix = fitz.Matrix(zoom, zoom) + + # 1. Renderování stránky do obrázku (Pixmap) + # colorspace=fitz.csGRAY zajistí převod do černobílé (Grayscale) + pix = page.get_pixmap(matrix=matrix, colorspace=fitz.csGRAY) + + # 2. Vytvoření nové stránky v cílovém dokumentu se stejnými rozměry + # Používáme původní rozměry stránky (rect), aby se PDF "nezmenšilo" vizuálně na monitoru + new_page = new_doc.new_page(width=page.rect.width, height=page.rect.height) + + # 3. Vložení zmenšeného a odbarveného obrázku zpět + # stream=pix.tobytes("jpg") zajistí silnou kompresi + new_page.insert_image(page.rect, stream=pix.tobytes("jpg", jpg_quality=quality)) + + # Vytvoření názvu výstupního souboru + output_path = input_path.replace(".pdf", "_bw_small.pdf") + + # Uložení s garbage collection (odstranění nepotřebných dat) a deflací + new_doc.save(output_path, garbage=4, deflate=True) + new_doc.close() + doc.close() + + # Výpis výsledku + new_size = os.path.getsize(output_path) + print(f"Hotovo. Uloženo jako: {output_path}") + print(f"Nová velikost: {new_size / 1024:.2f} KB") + + except Exception as e: + print(f"Došlo k chybě: {e}") + + +# --- SPUŠTĚNÍ --- +# Použití raw stringu (r''), aby Python neinterpretoval zpětná lomítka jako escape znaky +file_path = r'u:\Dropbox\Ordinace\Dokumentace_ke_zpracování\AdobeMakeSmaller\90df6f84-72c8-40b8-8993-ce7e244b0cea.pdf' + +# Můžete experimentovat s parametry. +# Pokud bude text nečitelný, zvyšte dpi na 200. Pokud je soubor moc velký, snižte quality na 40. +compress_and_grayscale_pdf(file_path, quality=50, dpi=120) \ No newline at end of file diff --git a/MakeSmallerPDF/3 MakeSmaller.py b/MakeSmallerPDF/3 MakeSmaller.py new file mode 100644 index 0000000..fd9a508 --- /dev/null +++ b/MakeSmallerPDF/3 MakeSmaller.py @@ -0,0 +1,37 @@ +import fitz # PyMuPDF + +file_path = r'u:\Dropbox\Ordinace\Dokumentace_ke_zpracování\AdobeMakeSmaller\90df6f84-72c8-40b8-8993-ce7e244b0cea.pdf' + +doc = fitz.open(file_path) + +print(f"Soubor: {file_path}") +print("-" * 40) + +for i, page in enumerate(doc): + # Získání seznamu obrázků na stránce + images = page.get_images(full=True) + + # Rozměry stránky v palcích (PDF body / 72) + page_w_inch = page.rect.width / 72 + page_h_inch = page.rect.height / 72 + + if images: + for img in images: + xref = img[0] + base_img = doc.extract_image(xref) + w = base_img["width"] + h = base_img["height"] + ext = base_img["ext"] + + # Výpočet DPI (Pixely / Palce) + dpi_x = w / page_w_inch + dpi_y = h / page_h_inch + + print(f"Strana {i + 1}:") + print(f" - Rozměry obrázku: {w} x {h} px") + print(f" - Formát: {ext}") + print(f" - Reálné DPI: cca {int(dpi_x)}") + else: + print(f"Strana {i + 1}: Žádný vložený obrázek (vektorový text).") + +print("-" * 40) \ No newline at end of file diff --git a/MakeSmallerPDF/4 MakeSmaller.py b/MakeSmallerPDF/4 MakeSmaller.py new file mode 100644 index 0000000..9a7837e --- /dev/null +++ b/MakeSmallerPDF/4 MakeSmaller.py @@ -0,0 +1,87 @@ +import fitz # PyMuPDF +from PIL import Image +import io +import os + +# --- NASTAVENÍ --- +INPUT_FILE = r'u:\Dropbox\Ordinace\Dokumentace_ke_zpracování\AdobeMakeSmaller\90df6f84-72c8-40b8-8993-ce7e244b0cea.pdf' + +# 1. Prahové hodnoty: Zúžíme výběr na nejpravděpodobnější rozsah +THRESHOLDS = [110, 130, 150, 170] + +# 2. DPI Varianty k testování +# 131 = Přesná polovina originálu (váš nápad) +# 150 = Standard +# 200 = Vysoká kvalita +# 262 = Originál (žádná ztráta detailů, jen ztráta barev) +DPI_LIST = [131, 150, 200, 262] + + +def generate_final_matrix(): + if not os.path.exists(INPUT_FILE): + print(f"Chyba: Soubor nenalezen.") + return + + # Příprava složky + base_folder = os.path.dirname(INPUT_FILE) + filename = os.path.basename(INPUT_FILE) + name_without_ext = os.path.splitext(filename)[0] + + output_dir = os.path.join(base_folder, "_TEST_DPI_MATH") + if not os.path.exists(output_dir): + os.makedirs(output_dir) + + print(f"Generuji varianty do: {output_dir}") + print("-" * 80) + print(f"{'DPI':<5} | {'Práh':<6} | {'Velikost':<12} | {'Poznámka'}") + print("-" * 80) + + doc = fitz.open(INPUT_FILE) + + for dpi in DPI_LIST: + # Přednačtení stránek v daném DPI + pages_at_dpi = [] + for page in doc: + zoom = dpi / 72 + matrix = fitz.Matrix(zoom, zoom) + pix = page.get_pixmap(matrix=matrix, colorspace=fitz.csGRAY) + pages_at_dpi.append(pix) + + for t in THRESHOLDS: + new_doc = fitz.open() + + for i, pix in enumerate(pages_at_dpi): + # Binarizace + img = Image.frombytes("L", [pix.width, pix.height], pix.samples) + img_bw = img.point(lambda x: 255 if x > t else 0, mode='1') + + # Uložení + buffer = io.BytesIO() + img_bw.save(buffer, format="PNG", optimize=True) + + # Vložení zpět + orig_rect = doc[i].rect + new_page = new_doc.new_page(width=orig_rect.width, height=orig_rect.height) + new_page.insert_image(orig_rect, stream=buffer.getvalue()) + + # Uložení + output_name = f"dpi{dpi}_t{t}.pdf" + output_path = os.path.join(output_dir, output_name) + new_doc.save(output_path, garbage=4, deflate=True) + new_doc.close() + + # Výpis + size_kb = os.path.getsize(output_path) / 1024 + + note = "" + if dpi == 131: note = "(Polovina originálu)" + if dpi == 262: note = "(Originální rozlišení)" + + print(f"{dpi:<5} | {t:<6} | {size_kb:<9.2f} KB | {note}") + + doc.close() + print("-" * 80) + + +if __name__ == "__main__": + generate_final_matrix() \ No newline at end of file diff --git a/MakeSmallerPDF/5 MakeSmaller.py b/MakeSmallerPDF/5 MakeSmaller.py new file mode 100644 index 0000000..7d5df8d --- /dev/null +++ b/MakeSmallerPDF/5 MakeSmaller.py @@ -0,0 +1,95 @@ +import fitz # PyMuPDF +from PIL import Image +import io +import os +import shutil + +# --- VAŠE VÍTĚZNÉ NASTAVENÍ --- +CHOSEN_DPI = 150 +CHOSEN_THRESHOLD = 150 + +# Cesty +INPUT_FOLDER = r'u:\Dropbox\Ordinace\Dokumentace_ke_zpracování\AdobeMakeSmaller' +OUTPUT_SUBFOLDER = '_HOTOVO' + + +def process_all_files(): + # Vytvoření výstupní složky + output_dir = os.path.join(INPUT_FOLDER, OUTPUT_SUBFOLDER) + if not os.path.exists(output_dir): + os.makedirs(output_dir) + + # Nalezení všech PDF (ignorujeme již hotové v podsložkách) + files = [f for f in os.listdir(INPUT_FOLDER) if f.lower().endswith('.pdf')] + + print(f"Startuji zpracování {len(files)} souborů.") + print(f"Nastavení: DPI={CHOSEN_DPI}, Práh={CHOSEN_THRESHOLD}") + print("-" * 60) + + success_count = 0 + + for filename in files: + input_path = os.path.join(INPUT_FOLDER, filename) + + # Přidáme '_bw' do názvu, aby se to nepletlo + name_without_ext = os.path.splitext(filename)[0] + output_filename = f"{name_without_ext}_bw.pdf" + output_path = os.path.join(output_dir, output_filename) + + try: + # Zpracování jednoho souboru + process_single_pdf(input_path, output_path) + + # Výpis výsledku + orig_size = os.path.getsize(input_path) / 1024 + new_size = os.path.getsize(output_path) / 1024 + ratio = (1 - (new_size / orig_size)) * 100 + + print(f"[OK] {filename}") + print(f" {orig_size:.1f} kB -> {new_size:.1f} kB (úspora {ratio:.0f} %)") + success_count += 1 + + # --- VOLITELNÉ: SMAZÁNÍ ORIGINÁLU --- + # Pokud chcete, aby skript po úspěchu smazal původní velký soubor, + # odkomentujte následující řádek (odstraňte mřížku #): + # os.remove(input_path) + + except Exception as e: + print(f"[CHYBA] {filename}: {e}") + + print("-" * 60) + print(f"Hotovo. Úspěšně zpracováno {success_count} z {len(files)} souborů.") + print(f"Výstupy jsou ve složce: {output_dir}") + + +def process_single_pdf(input_path, output_path): + doc = fitz.open(input_path) + new_doc = fitz.open() + + for page in doc: + # 1. Renderování stránky (Downsampling na 150 DPI) + zoom = CHOSEN_DPI / 72 + matrix = fitz.Matrix(zoom, zoom) + pix = page.get_pixmap(matrix=matrix, colorspace=fitz.csGRAY) + + # 2. Binarizace (Threshold 150) + img = Image.frombytes("L", [pix.width, pix.height], pix.samples) + img_bw = img.point(lambda x: 255 if x > CHOSEN_THRESHOLD else 0, mode='1') + + # 3. Uložení 1-bitového obrázku + buffer = io.BytesIO() + img_bw.save(buffer, format="PNG", optimize=True) + + # 4. Vložení do nového PDF + # Zachováme fyzické rozměry stránky (aby se netiskla jako známka) + new_page = new_doc.new_page(width=page.rect.width, height=page.rect.height) + new_page.insert_image(page.rect, stream=buffer.getvalue()) + + # Uložení s maximální kompresí + new_doc.save(output_path, garbage=4, deflate=True) + new_doc.close() + doc.close() + + +if __name__ == "__main__": + process_all_files() \ No newline at end of file diff --git a/MakeSmallerPDF/99 TestOCR.py b/MakeSmallerPDF/99 TestOCR.py new file mode 100644 index 0000000..a69bd7c --- /dev/null +++ b/MakeSmallerPDF/99 TestOCR.py @@ -0,0 +1,67 @@ +import fitz # PyMuPDF +import pytesseract +from PIL import Image +import os +import re + +# --- NASTAVENÍ --- +PATH_TO_TESSERACT = r'C:\Program Files\Tesseract-OCR\tesseract.exe' +INPUT_FILE = r'u:\Dropbox\Ordinace\Dokumentace_ke_zpracování\AdobeMakeSmaller\6ed31e44-0e7d-4118-8912-c3e583781459.pdf' + +# Nastavíme Tesseract +pytesseract.pytesseract.tesseract_cmd = PATH_TO_TESSERACT + + +def debug_ocr_output(): + if not os.path.exists(INPUT_FILE): + print(f"Soubor nenalezen: {INPUT_FILE}") + return + + print(f"ANALÝZA SOUBORU: {os.path.basename(INPUT_FILE)}") + doc = fitz.open(INPUT_FILE) + + # Projdeme první stranu (RČ bývá tam) + for i, page in enumerate(doc): + if i > 0: break # Stačí nám 1. strana pro test + + print(f"\n--- STRANA {i + 1} (300 DPI) ---") + + # 1. Renderování ve vysoké kvalitě (stejně jako v 'Ultimate' skriptu) + # Pokud je sken nekvalitní, Tesseract potřebuje velké rozlišení + zoom = 300 / 72 + matrix = fitz.Matrix(zoom, zoom) + pix = page.get_pixmap(matrix=matrix, colorspace=fitz.csGRAY) + img = Image.frombytes("L", [pix.width, pix.height], pix.samples) + + # 2. OCR - Získání surového textu + # config='--psm 3' je standardní automatická segmentace stránky + raw_text = pytesseract.image_to_string(img, lang='ces', config='--psm 3') + + print(">>> SUROVÝ TEXT Z TESSERACTU (ZAČÁTEK) <<<") + print("-" * 50) + print(raw_text) + print("-" * 50) + print(">>> SUROVÝ TEXT Z TESSERACTU (KONEC) <<<") + + # 3. Test Regexu na tomto textu + print("\n--- TEST HLEDÁNÍ RČ ---") + + # Standardní Regex + strict_pattern = r'\b\d{6}\s*[\/]?\s*\d{3,4}\b' + strict_matches = re.findall(strict_pattern, raw_text) + print(f"Přísný filtr (očekává jen čísla): {strict_matches}") + + # Volnější Regex (hledá i chyby OCR jako 'O' místo '0' nebo 'l' místo '1') + # \d -> číslice + # [O0] -> nula nebo O + # [lI1] -> jednička, malé L nebo velké i + loose_pattern = r'\b[0-9O]{6}\s*[\/ilI1]?\s*[0-9O]{3,4}\b' + loose_matches = re.findall(loose_pattern, raw_text) + + if loose_matches and not strict_matches: + print(f"⚠️ POZOR: Našel jsem RČ jen pomocí volného filtru (obsahuje překlepy OCR): {loose_matches}") + print(" -> Bude potřeba upravit čistící funkci.") + + +if __name__ == "__main__": + debug_ocr_output() \ No newline at end of file diff --git a/MakeSmallerPDF/991 test oCR.py b/MakeSmallerPDF/991 test oCR.py new file mode 100644 index 0000000..81f26b9 --- /dev/null +++ b/MakeSmallerPDF/991 test oCR.py @@ -0,0 +1,67 @@ +import fitz # PyMuPDF +import pytesseract +from PIL import Image +import os +import re + +# --- NASTAVENÍ --- +PATH_TO_TESSERACT = r'C:\Program Files\Tesseract-OCR\tesseract.exe' +INPUT_FILE = r'u:\Dropbox\Ordinace\Dokumentace_ke_zpracování\AdobeMakeSmaller\9b79f621-30ad-4468-85fe-6f2fd76289ce.pdf' + +# Nastavíme Tesseract +pytesseract.pytesseract.tesseract_cmd = PATH_TO_TESSERACT + + +def debug_ocr_output(): + if not os.path.exists(INPUT_FILE): + print(f"Soubor nenalezen: {INPUT_FILE}") + return + + print(f"ANALÝZA SOUBORU: {os.path.basename(INPUT_FILE)}") + doc = fitz.open(INPUT_FILE) + + # Projdeme první stranu (RČ bývá tam) + for i, page in enumerate(doc): + if i > 0: break # Stačí nám 1. strana pro test + + print(f"\n--- STRANA {i + 1} (300 DPI) ---") + + # 1. Renderování ve vysoké kvalitě (stejně jako v 'Ultimate' skriptu) + # Pokud je sken nekvalitní, Tesseract potřebuje velké rozlišení + zoom = 300 / 72 + matrix = fitz.Matrix(zoom, zoom) + pix = page.get_pixmap(matrix=matrix, colorspace=fitz.csGRAY) + img = Image.frombytes("L", [pix.width, pix.height], pix.samples) + + # 2. OCR - Získání surového textu + # config='--psm 3' je standardní automatická segmentace stránky + raw_text = pytesseract.image_to_string(img, lang='ces', config='--psm 3') + + print(">>> SUROVÝ TEXT Z TESSERACTU (ZAČÁTEK) <<<") + print("-" * 50) + print(raw_text) + print("-" * 50) + print(">>> SUROVÝ TEXT Z TESSERACTU (KONEC) <<<") + + # 3. Test Regexu na tomto textu + print("\n--- TEST HLEDÁNÍ RČ ---") + + # Standardní Regex + strict_pattern = r'\b\d{6}\s*[\/]?\s*\d{3,4}\b' + strict_matches = re.findall(strict_pattern, raw_text) + print(f"Přísný filtr (očekává jen čísla): {strict_matches}") + + # Volnější Regex (hledá i chyby OCR jako 'O' místo '0' nebo 'l' místo '1') + # \d -> číslice + # [O0] -> nula nebo O + # [lI1] -> jednička, malé L nebo velké i + loose_pattern = r'\b[0-9O]{6}\s*[\/ilI1]?\s*[0-9O]{3,4}\b' + loose_matches = re.findall(loose_pattern, raw_text) + + if loose_matches and not strict_matches: + print(f"⚠️ POZOR: Našel jsem RČ jen pomocí volného filtru (obsahuje překlepy OCR): {loose_matches}") + print(" -> Bude potřeba upravit čistící funkci.") + + +if __name__ == "__main__": + debug_ocr_output() \ No newline at end of file diff --git a/RenameMedevioPrilohy/10 RenameMedevioPrilohy.py b/RenameMedevioPrilohy/10 RenameMedevioPrilohy.py index 7fad288..fc7f2ca 100644 --- a/RenameMedevioPrilohy/10 RenameMedevioPrilohy.py +++ b/RenameMedevioPrilohy/10 RenameMedevioPrilohy.py @@ -1,3 +1,4 @@ + #!/usr/bin/env python3 # -*- coding: utf-8 -*-