Spaces:
Sleeping
Sleeping
| """Post-processing PDF (pip-only). | |
| Obiettivo: | |
| - rimuovere pagine *visivamente* vuote (tipicamente solo footer/logo e numero pagina) | |
| che possono comparire in template DOCX complessi dopo la conversione. | |
| Implementazione: | |
| - usa PyMuPDF (fitz) per rasterizzare ogni pagina a bassa risoluzione | |
| - calcola la frazione di pixel "quasi bianchi" e il numero di pixel non bianchi | |
| - se la pagina è "troppo bianca" e con pochissimi pixel scuri => considerata vuota | |
| - crea un nuovo PDF senza quelle pagine. | |
| Nota: | |
| La soglia è tarata per il caso tipico "pagina bianca con solo numero pagina". | |
| """ | |
| from __future__ import annotations | |
| from pathlib import Path | |
| from typing import List | |
| def remove_blank_pages_pdf( | |
| pdf_path: Path, | |
| *, | |
| zoom: float = 0.35, | |
| white_thr: int = 245, | |
| white_frac_thr: float = 0.995, | |
| max_nonwhite_pixels: int = 3500, | |
| ) -> int: | |
| """Rimuove pagine visivamente vuote da un PDF. | |
| Ritorna il numero di pagine rimosse. | |
| """ | |
| import fitz # PyMuPDF | |
| import numpy as np | |
| pdf_path = Path(pdf_path) | |
| doc = fitz.open(str(pdf_path)) | |
| if doc.page_count == 0: | |
| return 0 | |
| keep: List[int] = [] | |
| for i in range(doc.page_count): | |
| page = doc.load_page(i) | |
| pix = page.get_pixmap(matrix=fitz.Matrix(zoom, zoom), alpha=False) | |
| img = np.frombuffer(pix.samples, dtype=np.uint8).reshape(pix.height, pix.width, 3) | |
| white = np.all(img >= white_thr, axis=2) | |
| white_frac = float(white.mean()) | |
| nonwhite = int((~white).sum()) | |
| # Se è molto bianca e con pochissimi pixel non bianchi => pagina vuota | |
| if not (white_frac >= white_frac_thr and nonwhite <= max_nonwhite_pixels): | |
| keep.append(i) | |
| removed = doc.page_count - len(keep) | |
| if removed <= 0: | |
| doc.close() | |
| return 0 | |
| new_doc = fitz.open() | |
| new_doc.insert_pdf(doc, from_page=min(keep), to_page=max(keep), start_at=0) | |
| # insert_pdf sopra copia range continuo: per keep non contiguo bisogna copiare singole pagine | |
| if len(keep) != (max(keep) - min(keep) + 1): | |
| new_doc = fitz.open() | |
| for i in keep: | |
| new_doc.insert_pdf(doc, from_page=i, to_page=i) | |
| doc.close() | |
| tmp = pdf_path.with_suffix(".tmp.pdf") | |
| new_doc.save(str(tmp)) | |
| new_doc.close() | |
| tmp.replace(pdf_path) | |
| return removed | |