notebookvb

This commit is contained in:
Vladimir Buzalka
2026-04-29 06:55:23 +02:00
parent a9c143ba24
commit daad4adeab
113 changed files with 16563 additions and 0 deletions
+101
View File
@@ -0,0 +1,101 @@
"""
Konverze JPG/PNG → PDF se správnou orientací stránky (A4).
Řeší:
- EXIF orientaci (fotky z telefonu/skeneru bývají otočené)
- Správné umístění na A4 stránce (na výšku nebo na šířku dle obsahu)
- Zachování kvality
Použití:
python jpg_to_pdf.py soubor.jpg
python jpg_to_pdf.py soubor.jpg vystup.pdf
"""
import io
import sys
from pathlib import Path
from PIL import Image, ImageOps
# A4 rozměry v mm
A4_W_MM = 210
A4_H_MM = 297
MARGIN_MM = 0 # bez okraje, tisk si řeší Acrobat (Fit to Print)
def fix_orientation(img: Image.Image) -> Image.Image:
"""Opraví rotaci podle EXIF dat (tag 274)."""
return ImageOps.exif_transpose(img)
def image_to_pdf(src: Path, dst: Path, dpi: int = 150, quality: int = 80, rotate_ccw: int = 0):
img = Image.open(src)
print(f" Originál: {img.size[0]}×{img.size[1]} px, mode={img.mode}, format={img.format}")
# 1. Oprav EXIF orientaci
img = fix_orientation(img)
print(f" Po EXIF korekci: {img.size[0]}×{img.size[1]} px")
# 2. Rotace dle parametru (od Claude nebo ručně)
if rotate_ccw and rotate_ccw != 0:
img = img.rotate(rotate_ccw, expand=True)
print(f" Po rotaci {rotate_ccw}° CCW: {img.size[0]}×{img.size[1]} px")
# 2. Převeď na RGB (PDF nepodporuje RGBA/P)
if img.mode in ("RGBA", "P", "LA"):
img = img.convert("RGB")
# 3. Urči orientaci stránky podle poměru stran obrázku
img_w, img_h = img.size
if img_w > img_h:
# Obrázek na šířku → stránka na šířku (A4 landscape)
page_w_mm, page_h_mm = A4_H_MM, A4_W_MM
print(f" Orientace stránky: na šířku (landscape)")
else:
# Obrázek na výšku → stránka na výšku (A4 portrait)
page_w_mm, page_h_mm = A4_W_MM, A4_H_MM
print(f" Orientace stránky: na výšku (portrait)")
# 4. Vypočti cílovou velikost s okrajem (mm → px při daném DPI)
mm_to_px = dpi / 25.4
max_w_px = int((page_w_mm - 2 * MARGIN_MM) * mm_to_px)
max_h_px = int((page_h_mm - 2 * MARGIN_MM) * mm_to_px)
# 5. Škáluj obrázek na stránku (zachovej poměr stran)
img.thumbnail((max_w_px, max_h_px), Image.LANCZOS)
print(f" Výsledná velikost obrázku: {img.size[0]}×{img.size[1]} px")
# 6. Vlož obrázek na bílé A4 plátno
page_w_px = int(page_w_mm * mm_to_px)
page_h_px = int(page_h_mm * mm_to_px)
canvas = Image.new("RGB", (page_w_px, page_h_px), "white")
offset_x = (page_w_px - img.size[0]) // 2
offset_y = (page_h_px - img.size[1]) // 2
canvas.paste(img, (offset_x, offset_y))
# 7. Ulož jako PDF
canvas.save(dst, "PDF", resolution=dpi, quality=quality)
print(f" ✓ Uloženo: {dst.name} ({dst.stat().st_size // 1024} KB)")
if __name__ == "__main__":
if sys.platform == "win32":
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8", errors="replace")
if len(sys.argv) < 2:
print("Použití: python jpg_to_pdf.py soubor.jpg [vystup.pdf] [rotace_ccw]")
print(" rotace_ccw: 0 / 90 / 180 / 270 (výchozí: 0)")
sys.exit(1)
src = Path(sys.argv[1])
if not src.exists():
print(f"Soubor nenalezen: {src}")
sys.exit(1)
dst = Path(sys.argv[2]) if len(sys.argv) > 2 else src.with_suffix(".pdf")
rotate_ccw = int(sys.argv[3]) if len(sys.argv) > 3 else 0
print(f"Konvertuji: {src.name}{dst.name}")
image_to_pdf(src, dst, rotate_ccw=rotate_ccw)