Files
RRS/scripts/optimize-carousel-images.py

43 lines
1.6 KiB
Python

"""Pre-scale the carousel imagery so browsers never upscale it.
The refined fabric shots top out at 1024-1376px, but the full-bleed hero paints
them across up to ~1920 CSS px (3840 device px on retina). Browsers enlarge them
at render time and the knit stitches smear. Resampling once with Lanczos plus a
light unsharp pass keeps the texture readable and, at these sizes, costs about
the same bytes as the originals. Requires Pillow. Generated assets are committed;
runtime needs nothing.
"""
from pathlib import Path
import sys
from PIL import Image, ImageFilter
ROOT = Path(__file__).resolve().parents[1]
TARGETS = [ROOT / "public" / "images" / "refined" / "hero",
ROOT / "public" / "images" / "refined" / "products"]
LONG_EDGE = 2048
QUALITY = 82
def optimize(path):
with Image.open(path) as source:
image = source.convert("RGB")
scale = LONG_EDGE / max(image.size)
if scale > 1:
image = image.resize(
(round(image.width * scale), round(image.height * scale)),
Image.Resampling.LANCZOS,
)
image = image.filter(ImageFilter.UnsharpMask(radius=1.0, percent=60, threshold=3))
before = path.stat().st_size
image.save(path, quality=QUALITY, optimize=True, progressive=True)
after = path.stat().st_size
print(f"{path.relative_to(ROOT)} {image.size} {before // 1024}KB -> {after // 1024}KB")
if __name__ == "__main__":
files = sorted(p for target in TARGETS for p in target.rglob("*.jpeg"))
if not files:
sys.exit("no carousel images found")
for file in files:
optimize(file)