#!/usr/bin/env python3 """把一张背景图处理成展示页用的背景:缩到最长边不超过 3840 像素、预先模糊、存成渐进式 JPEG。 用法:python web/display/scripts/prepare-bg.py <原图> <输出,例如 web/display/src/assets/bg.jpg> [--sigma 10] 为什么预先模糊:背景层会随鼠标移动,如果让浏览器用 CSS filter 现场模糊这么大的一层,每次移动都要重新算, 和卡片自己的 backdrop-filter 叠在一起很吃 GPU(低配机器上会出现闪烁、层叠错乱)。图片本身已经是模糊的,移动就只是搬一块贴图。 模糊半径默认按宽度的 0.6% 算(1672 像素宽约 10),和原来 CSS 里 blur(10px) 的效果相近;想更糊或更清楚用 --sigma。 """ import argparse import os from PIL import Image, ImageFilter def main() -> None: parser = argparse.ArgumentParser() parser.add_argument("source") parser.add_argument("target") parser.add_argument("--sigma", type=float, default=None, help="模糊半径(像素,按处理后的图);默认宽度的 0.6%%") parser.add_argument("--max-side", type=int, default=3840) parser.add_argument("--quality", type=int, default=92) args = parser.parse_args() image = Image.open(args.source).convert("RGB") longest = max(image.size) if longest > args.max_side: scale = args.max_side / longest image = image.resize((round(image.width * scale), round(image.height * scale)), Image.LANCZOS) sigma = args.sigma if args.sigma is not None else image.width * 0.006 image = image.filter(ImageFilter.GaussianBlur(sigma)) image.save(args.target, quality=args.quality, optimize=True, progressive=True, subsampling=0) print(f"{args.target}: {image.width}x{image.height}, blur sigma {sigma:.1f}, {os.path.getsize(args.target) // 1024} KB") if __name__ == "__main__": main()