37 lines
1.8 KiB
Python
37 lines
1.8 KiB
Python
#!/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()
|