站点:纯静态 HTML + CSS + 原生 JS,零框架零构建
页面:首页 / 合作品牌 / 荣誉资质 / 客户案例 / 关于我们
内容:
- site/ 站点本体(含已压缩 webp 图片,约 4.8 MB)
- deploy/ Docker Compose / Caddy / Apache 部署配置
- _tools/ 开发自检脚本与部署脚本
- Dockerfile 自建 nginx 镜像方案
- README.md 项目文档
设计:品牌黄 #ffc107 + 白,深蓝仅用于页脚;菜单长期置顶;
交互动效只加在关键词与区块级元素上。
素材说明:原始素材(背景图/老网站/方案/荣誉资质/合作品牌,约 290 MB)
未纳入版本控制,站点使用的是 site/assets 内已处理压缩的图片。
94 lines
3.5 KiB
Python
94 lines
3.5 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""增量素材:新首屏图(背景图/轮播/lunbo01(2).png)+ 用「方案」目录图替换行业方案卡封面。
|
||
只做新增/覆盖,不重建全部资源。运行: python _tools/build_assets_v2.py
|
||
"""
|
||
import base64
|
||
import io
|
||
import os
|
||
from PIL import Image, ImageFilter
|
||
|
||
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||
IMG = os.path.join(ROOT, "site", "assets", "img")
|
||
LQIP_LINES = []
|
||
|
||
|
||
def resize_to_width(im, width):
|
||
if im.width <= width:
|
||
return im.copy()
|
||
return im.resize((width, round(im.height * width / im.width)), Image.LANCZOS)
|
||
|
||
|
||
def save_webp(im, path, q=80):
|
||
im.convert("RGB").save(path, "WEBP", quality=q, method=6)
|
||
print(" %-46s %6.1f KB" % (os.path.basename(path), os.path.getsize(path) / 1024))
|
||
|
||
|
||
def lqip(im, key, width=26):
|
||
small = resize_to_width(im.convert("RGB"), width).filter(ImageFilter.GaussianBlur(1.2))
|
||
buf = io.BytesIO()
|
||
small.save(buf, "JPEG", quality=45)
|
||
LQIP_LINES.append('[data-lqip="%s"]{background-image:url(data:image/jpeg;base64,%s)}'
|
||
% (key, base64.b64encode(buf.getvalue()).decode()))
|
||
|
||
|
||
def main():
|
||
print("== 新首屏图 hero-1(来自 背景图/轮播/lunbo01(2).png)==")
|
||
src = os.path.join(ROOT, "背景图", "轮播", "lunbo01(2).png")
|
||
im = Image.open(src)
|
||
print(" 源尺寸 %dx%d" % im.size)
|
||
save_webp(resize_to_width(im, 1920), os.path.join(IMG, "hero", "hero-1.webp"), 82)
|
||
save_webp(resize_to_width(im, 1200), os.path.join(IMG, "hero", "hero-1-md.webp"), 78)
|
||
save_webp(resize_to_width(im, 2880), os.path.join(IMG, "hero", "hero-1@2x.webp"), 74)
|
||
lqip(im, "hero/hero-1")
|
||
|
||
print("== 行业方案卡封面(来自 方案/ 目录,原图无文字)==")
|
||
mapping = [
|
||
("方案/地产.png", "realestate"),
|
||
("方案/工业.png", "industry"),
|
||
("方案/金融.png", "finance"),
|
||
("方案/三甲医院.png", "medical"),
|
||
]
|
||
for rel, slug in mapping:
|
||
p = os.path.join(ROOT, rel)
|
||
if not os.path.exists(p):
|
||
print(" ! 缺少 " + rel)
|
||
continue
|
||
s = Image.open(p).convert("RGB")
|
||
h = round(1000 * 3 / 4)
|
||
# 居中裁剪成 4:3,保证卡片里构图完整
|
||
tr = 4 / 3
|
||
if s.width / s.height > tr:
|
||
nw = round(s.height * tr)
|
||
left = (s.width - nw) // 2
|
||
s = s.crop((left, 0, left + nw, s.height))
|
||
else:
|
||
nh = round(s.width / tr)
|
||
top = max(0, (s.height - nh) // 2)
|
||
s = s.crop((0, top, s.width, top + nh))
|
||
s = s.resize((1000, h), Image.LANCZOS)
|
||
save_webp(s, os.path.join(IMG, "solutions", slug + ".webp"), 80)
|
||
lqip(s, "solutions/" + slug)
|
||
|
||
print("== 更新 lqip.css / lqip.js 中的对应条目 ==")
|
||
for target in ("lqip.css", "lqip.js"):
|
||
path = os.path.join(ROOT, "site", "assets", target)
|
||
with open(path, encoding="utf-8") as f:
|
||
text = f.read()
|
||
for line in LQIP_LINES:
|
||
key = line.split('"')[1]
|
||
if target == "lqip.css":
|
||
import re
|
||
text = re.sub(r'\[data-lqip="%s"\]\{background-image:url\([^)]*\)\}' % re.escape(key),
|
||
line, text)
|
||
else:
|
||
import re
|
||
text = re.sub(r'"%s":\s*"[^"]*"' % re.escape(key),
|
||
'"%s": "%s"' % (key, line.split("url(")[1][:-1]), text)
|
||
with open(path, "w", encoding="utf-8") as f:
|
||
f.write(text)
|
||
print(" 已更新 " + target)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|