notebookvb
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
# Define the target directory
|
||||
target_path = Path(r"U:\Dropbox\Ordinace\Dokumentace_ke_zpracování\MP")
|
||||
|
||||
|
||||
def rename_folders():
|
||||
# Ensure the path exists
|
||||
if not target_path.exists():
|
||||
print(f"Error: The path {target_path} does not exist.")
|
||||
return
|
||||
|
||||
# Iterate through items in the directory
|
||||
for folder in target_path.iterdir():
|
||||
# Only process directories
|
||||
if folder.is_dir():
|
||||
original_name = folder.name
|
||||
|
||||
# Check if name starts with the triangle
|
||||
if original_name.startswith("▲"):
|
||||
# 1. Remove the triangle from the start
|
||||
name_without_tri = original_name[1:]
|
||||
|
||||
# 2. Prepare the name to be at least 10 chars long
|
||||
# (so the triangle can sit at index 10 / position 11)
|
||||
clean_name = name_without_tri.ljust(10)
|
||||
|
||||
# 3. Construct new name: first 10 chars + triangle + the rest
|
||||
new_name = clean_name[:10] + "▲" + clean_name[10:]
|
||||
|
||||
# Remove trailing spaces if the original name was short
|
||||
# but you don't want extra spaces at the very end
|
||||
new_name = new_name.rstrip()
|
||||
|
||||
new_folder_path = folder.parent / new_name
|
||||
|
||||
try:
|
||||
print(f"Renaming: '{original_name}' -> '{new_name}'")
|
||||
folder.rename(new_folder_path)
|
||||
except Exception as e:
|
||||
print(f"Could not rename {original_name}: {e}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
rename_folders()
|
||||
@@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Compress PDF — output DPI and JPEG quality are chosen automatically
|
||||
based on the detected resolution of the source PDF.
|
||||
|
||||
Usage: python compress_pdf.py <input.pdf> [output.pdf]
|
||||
python compress_pdf.py (processes all PDFs in current folder)
|
||||
Output filename: original_name (139 kB).pdf
|
||||
"""
|
||||
|
||||
import sys
|
||||
import fitz
|
||||
from pathlib import Path
|
||||
|
||||
# ==============================
|
||||
# COMPRESSION TABLE
|
||||
# Detected source DPI -> (output DPI, JPEG quality)
|
||||
# Rows are evaluated top-to-bottom; first match wins.
|
||||
# ==============================
|
||||
#
|
||||
# src_dpi_min src_dpi_max out_dpi jpeg_quality
|
||||
COMPRESSION_TABLE = [
|
||||
( 0, 99, 72, 60), # very low res — already small, compress hard
|
||||
( 100, 149, 100, 70), # low res
|
||||
( 150, 249, 150, 80), # standard scan (our tested sweet spot)
|
||||
( 250, 399, 150, 80), # good scan — downsample to 150 is fine
|
||||
( 400, 599, 200, 85), # high res scan
|
||||
( 600, 9999, 150, 80), # very high res / professional scan
|
||||
]
|
||||
|
||||
|
||||
def detect_source_dpi(src: fitz.Document) -> int:
|
||||
"""Estimate source DPI from the largest image on the first page."""
|
||||
page = src[0]
|
||||
images = page.get_images(full=True)
|
||||
if not images:
|
||||
return 150 # no raster images — use default
|
||||
|
||||
# Find the largest image by pixel area
|
||||
best = max(images, key=lambda img: img[2] * img[3]) # width * height
|
||||
img_w_px, img_h_px = best[2], best[3]
|
||||
|
||||
# Page size in inches (1 point = 1/72 inch)
|
||||
page_w_in = page.rect.width / 72.0
|
||||
page_h_in = page.rect.height / 72.0
|
||||
|
||||
dpi_x = img_w_px / page_w_in if page_w_in else 0
|
||||
dpi_y = img_h_px / page_h_in if page_h_in else 0
|
||||
return round((dpi_x + dpi_y) / 2)
|
||||
|
||||
|
||||
def pick_settings(source_dpi: int) -> tuple[int, int]:
|
||||
for min_dpi, max_dpi, out_dpi, quality in COMPRESSION_TABLE:
|
||||
if min_dpi <= source_dpi <= max_dpi:
|
||||
return out_dpi, quality
|
||||
# fallback to last row
|
||||
return COMPRESSION_TABLE[-1][2], COMPRESSION_TABLE[-1][3]
|
||||
|
||||
|
||||
def compress(input_path: Path, output_path: Path = None):
|
||||
src = fitz.open(input_path)
|
||||
|
||||
source_dpi = detect_source_dpi(src)
|
||||
out_dpi, jpeg_quality = pick_settings(source_dpi)
|
||||
|
||||
print(f" zdroj ~{source_dpi} DPI -> komprese {out_dpi} DPI / JPEG q{jpeg_quality}")
|
||||
|
||||
zoom = out_dpi / 72.0
|
||||
mat = fitz.Matrix(zoom, zoom)
|
||||
|
||||
out_doc = fitz.open()
|
||||
for page in src:
|
||||
pix = page.get_pixmap(matrix=mat, colorspace=fitz.csRGB)
|
||||
img_bytes = pix.tobytes("jpeg", jpg_quality=jpeg_quality)
|
||||
img_doc = fitz.open("pdf", fitz.open("jpeg", img_bytes).convert_to_pdf())
|
||||
rect = page.rect
|
||||
new_page = out_doc.new_page(width=rect.width, height=rect.height)
|
||||
new_page.show_pdf_page(new_page.rect, img_doc, 0)
|
||||
src.close()
|
||||
|
||||
tmp = input_path.with_suffix(".tmp.pdf")
|
||||
out_doc.save(tmp, deflate=True, garbage=4)
|
||||
out_doc.close()
|
||||
|
||||
size_kb = round(tmp.stat().st_size / 1024)
|
||||
|
||||
if output_path is None:
|
||||
output_path = input_path.parent / f"{input_path.stem} ({size_kb} kB).pdf"
|
||||
|
||||
if output_path.exists():
|
||||
output_path.unlink()
|
||||
tmp.rename(output_path)
|
||||
|
||||
orig_kb = round(input_path.stat().st_size / 1024)
|
||||
saving = (1 - size_kb / orig_kb) * 100
|
||||
print(f" {input_path.name} -> {output_path.name} (bylo {orig_kb} kB, uspora {saving:.0f}%)")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) >= 2:
|
||||
inp = Path(sys.argv[1])
|
||||
out = Path(sys.argv[2]) if len(sys.argv) >= 3 else None
|
||||
compress(inp, out)
|
||||
else:
|
||||
folder = Path(__file__).parent
|
||||
pdfs = [p for p in folder.glob("*.pdf") if not p.name.endswith(").pdf") and p.stem != Path(__file__).stem]
|
||||
if not pdfs:
|
||||
print("Zadne PDF k zpracovani.")
|
||||
for pdf in pdfs:
|
||||
compress(pdf)
|
||||
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Compress a PDF into multiple variants at different DPI / JPEG quality settings.
|
||||
Uses PyMuPDF (fitz) — renders each page as JPEG image, saves back as PDF.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import fitz # PyMuPDF
|
||||
from pathlib import Path
|
||||
|
||||
INPUT = Path(r"u:\Medevio\50 Různé testy\MinimizeOptimizePDF\afd1823b-8277-44a2-84e1-db89a0ccd134.pdf")
|
||||
OUT_DIR = INPUT.parent
|
||||
|
||||
VARIANTS = [
|
||||
# (label, dpi, jpeg_quality)
|
||||
("300dpi_q90", 300, 90),
|
||||
("200dpi_q85", 200, 85),
|
||||
("150dpi_q80", 150, 80),
|
||||
("120dpi_q75", 120, 75),
|
||||
("96dpi_q70", 96, 70),
|
||||
("72dpi_q60", 72, 60),
|
||||
]
|
||||
|
||||
src = fitz.open(INPUT)
|
||||
original_size = INPUT.stat().st_size
|
||||
print(f"Originál: {INPUT.name} ({original_size / 1024:.0f} KB)\n")
|
||||
print(f"{'Varianta':<20} {'DPI':>5} {'Kvalita':>8} {'Velikost':>12} {'Úspora':>8}")
|
||||
print("-" * 58)
|
||||
|
||||
for label, dpi, quality in VARIANTS:
|
||||
out_path = OUT_DIR / f"{INPUT.stem}_{label}.pdf"
|
||||
zoom = dpi / 72.0
|
||||
mat = fitz.Matrix(zoom, zoom)
|
||||
|
||||
out_doc = fitz.open()
|
||||
for page in src:
|
||||
pix = page.get_pixmap(matrix=mat, colorspace=fitz.csRGB)
|
||||
img_bytes = pix.tobytes("jpeg", jpg_quality=quality)
|
||||
|
||||
# Create a new PDF page with the same physical dimensions
|
||||
img_doc = fitz.open("pdf", fitz.open("jpeg", img_bytes).convert_to_pdf())
|
||||
# Scale page back to original size
|
||||
rect = page.rect
|
||||
new_page = out_doc.new_page(width=rect.width, height=rect.height)
|
||||
new_page.show_pdf_page(new_page.rect, img_doc, 0)
|
||||
|
||||
out_doc.save(out_path, deflate=True, garbage=4)
|
||||
out_doc.close()
|
||||
|
||||
size = out_path.stat().st_size
|
||||
size_kb = round(size / 1024)
|
||||
final_path = OUT_DIR / f"{INPUT.stem}_{label} ({size_kb} kB).pdf"
|
||||
out_path.rename(final_path)
|
||||
|
||||
saving = (1 - size / original_size) * 100
|
||||
print(f"{label:<20} {dpi:>5} {quality:>8} {size_kb:>9} kB {saving:>7.0f}%")
|
||||
|
||||
src.close()
|
||||
print("\nHotovo.")
|
||||
Reference in New Issue
Block a user