feat: 沙香科技官网 v2.2 基线(深色科技风/双语/局域网+公网双部署)
This commit is contained in:
71
tools/make_logo_light.py
Normal file
71
tools/make_logo_light.py
Normal file
@@ -0,0 +1,71 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
生成深色站反白版 logo(logo-light.png):
|
||||
1. flood-fill 镂空深蓝底(容差 84 = v1 验证成功参数,能吃掉 #000020 底色)
|
||||
2. 不透明内容亮度反转 L' = 1 - L(黑字→白字,红/青/绿提亮,色相保留)
|
||||
深色页黑字看不清、白底块又突兀,反白是深色站标准解法。
|
||||
用法: uv run --with pillow python3 tools/make_logo_light.py
|
||||
"""
|
||||
import colorsys
|
||||
from collections import deque
|
||||
|
||||
from PIL import Image
|
||||
|
||||
SRC = 'assets/img/logo.png'
|
||||
OUT = 'assets/img/logo-light.png'
|
||||
TOL = 84 # 曼哈顿距离容差(v1 实测:清除 83%、红色主体完整保留)
|
||||
|
||||
im = Image.open(SRC).convert('RGBA')
|
||||
w, h = im.size
|
||||
px = im.load()
|
||||
|
||||
# --- flood-fill 清底 ---
|
||||
corners = [px[0, 0], px[w-1, 0], px[0, h-1], px[w-1, h-1]]
|
||||
bg = tuple(sum(c[i] for c in corners) // 4 for i in range(3))
|
||||
|
||||
def is_bg(p):
|
||||
if p[3] < 10:
|
||||
return True
|
||||
return abs(p[0]-bg[0]) + abs(p[1]-bg[1]) + abs(p[2]-bg[2]) <= TOL
|
||||
|
||||
seen = [[False]*w for _ in range(h)]
|
||||
q = deque()
|
||||
for x in range(w):
|
||||
q.extend(((x, 0), (x, h-1)))
|
||||
for y in range(h):
|
||||
q.extend(((0, y), (w-1, y)))
|
||||
cleared = 0
|
||||
while q:
|
||||
x, y = q.popleft()
|
||||
if x < 0 or x >= w or y < 0 or y >= h or seen[y][x]:
|
||||
continue
|
||||
seen[y][x] = True
|
||||
p = px[x, y]
|
||||
if not is_bg(p):
|
||||
continue
|
||||
px[x, y] = (0, 0, 0, 0)
|
||||
cleared += 1
|
||||
q.extend(((x+1, y), (x-1, y), (x, y+1), (x, y-1)))
|
||||
ratio = cleared / (w * h)
|
||||
assert 0.10 < ratio < 0.92, f'镂空异常: 清除 {ratio:.0%}'
|
||||
|
||||
# --- 暗部提亮、亮部保留(logo 含 ~20% 浅色元素,全量反转会把它们变黑) ---
|
||||
# L' = max(L, 1-L):暗像素翻到亮侧(黑→白),亮像素不动,色相全保留
|
||||
opaque = [px[x, y] for y in range(h) for x in range(w) if px[x, y][3] > 128]
|
||||
assert opaque, '镂空后内容为空'
|
||||
|
||||
for y in range(h):
|
||||
for x in range(w):
|
||||
r, g, b, a = px[x, y]
|
||||
if a == 0:
|
||||
continue
|
||||
hh, ll, ss = colorsys.rgb_to_hls(r / 255, g / 255, b / 255)
|
||||
r2, g2, b2 = colorsys.hls_to_rgb(hh, max(ll, 1 - ll), ss)
|
||||
px[x, y] = (round(r2 * 255), round(g2 * 255), round(b2 * 255), a)
|
||||
|
||||
im.save(OUT, 'PNG', optimize=True)
|
||||
|
||||
# 验证:反白后所有不透明像素亮度下限
|
||||
final = [px[x, y] for y in range(h) for x in range(w) if px[x, y][3] > 128]
|
||||
dark = sum(1 for p in final if 0.299*p[0]+0.587*p[1]+0.114*p[2] < 90) / len(final)
|
||||
print(f'完成: {OUT} 镂空 {ratio:.0%},暗部像素剩 {dark:.1%}(应为 0)')
|
||||
Reference in New Issue
Block a user