Files
Normtor/tools/build_images.py
T
NotPika69andClaude Opus 5.5 bec24e5bbc Website-Entwurf für HEB Bauelemente (normtor.de)
Akquise-Demo mit Startseite (Tor-Intro, 24-h-Renovierung mit Uhr,
Über uns, Fachbetrieb statt Discount), Galerie mit Filter und
Großansicht, Kontaktseite mit Anfrageformular sowie Impressum- und
Datenschutz-Entwürfen. Statisches HTML/CSS/JS, Seiten und Bilder
werden über tools/ erzeugt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 22:52:10 +02:00

76 lines
3.1 KiB
Python

"""Wandelt die Originalfotos aus tools/orig in AVIF und WebP (800 px und volle Breite) für assets/img um.
Die Originale stammen von der alten Seite normtor.de. Neue Fotos in tools/orig ablegen, unten in
IMAGES eintragen und neu erzeugen:
python3 tools/build_images.py (braucht Pillow mit AVIF: pip install pillow)
"""
from pathlib import Path
from PIL import Image, ImageOps
ROOT = Path(__file__).resolve().parent.parent
SRC = ROOT / "tools/orig"
OUT = ROOT / "assets/img"
# Ziel-Name: (Quelldatei, Zuschnitt als (links, oben, rechts, unten) in Pixeln oder None)
IMAGES = {
"hero": ("dst_superior_style_graualu.jpg", None),
"haas": ("haas.jpg", (80, 0, 880, 960)),
"flair-1": ("flair_db_703_1.jpg", None),
"flair-2": ("flair_db_703_2.jpg", None),
"garagenhof": ("web1.jpg", None),
"doppelgarage-beige": ("web2.jpg", None),
"anthrazit-solo": ("web3.jpg", None),
"doppelgarage-hell": ("web4.jpg", None),
"anthrazit-iso": ("web5.jpg", None),
"condor-granit": ("condoor_granit.jpg", None),
"condor-schraegschnitt": ("condoor_schraegschnitt1.jpg", None),
"condor-ligna": ("condoor_wood_ligna_light2.jpg", None),
"condor-schlupftuer": ("condor-mit-schlupftuerer.jpg", None),
"smart-style": ("dst_smart_style_anth_glatt.jpg", None),
"smart-trend": ("dst_smart_trend_eiche_dunkel_woodgrain.jpg", None),
"superior-eiche": ("dst_superior_eiche_hell_style_glatt_01.jpg", None),
"superior-linea": ("dst_superior_linea_verkehrsweiss_glatt.jpg", None),
"superior-graualu": ("dst_superior_style_graualu.jpg", None),
"sst-style": ("sst_style_anthrazitgrau_01.jpg", None),
"sst-trend": ("sst_trend_anthrazitgrau_01.jpg", None),
"sst-design": ("sst.gif", None),
"mueller-muenster": ("mueller_muenster.jpg", None),
"essenbach-ohu": ("essenbach-ohu1.jpg", None),
"elegant": ("elegant-taubenblau.gif", None),
"variant": ("modell-variant.jpg", None),
"rustiko": ("eder2.jpg", None),
"prominent-rottenburg": ("jahnstr-rottenburg.jpg", None),
"eurostyle-iso": ("muech3.jpg", None),
"topline-iso": ("rott2.jpg", None),
}
def save(im, name, w):
if im.width > w:
im = im.resize((w, round(im.height * w / im.width)), Image.LANCZOS)
im.save(OUT / f"{name}-{w}.webp", quality=80, method=6)
im.save(OUT / f"{name}-{w}.avif", quality=58, speed=4)
def main():
OUT.mkdir(parents=True, exist_ok=True)
for old in OUT.glob("*"):
old.unlink()
for name, (src, crop) in IMAGES.items():
im = ImageOps.exif_transpose(Image.open(SRC / src)).convert("RGB")
if crop:
im = im.crop(crop)
# Kleine Altbilder (350 px) gibt es nur als -800 (in Originalgröße), große zusätzlich als -1200
save(im, name, 800)
if im.width > 800:
save(im, name, 1200)
# Vorschaubild für Messenger und soziale Netzwerke
hero = Image.open(SRC / IMAGES["hero"][0]).convert("RGB")
ImageOps.fit(hero, (1200, 630), centering=(0.5, 0.6)).save(OUT / "og.jpg", quality=82)
print(f"{len(IMAGES)} Bilder nach {OUT.relative_to(ROOT)} geschrieben")
if __name__ == "__main__":
main()