chore: tidy repo - DESIGN.md & scoring rules into docs/, icon generators into tools/, drop one-off junk, refresh app README
ci / test (push) Canceled after 0s
ci / test (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
# 生成 Footprints 应用图标:品牌蓝圆角方块 + 白色抽象足迹
|
||||
from PIL import Image, ImageDraw
|
||||
import os
|
||||
|
||||
OUT = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'app', 'src-tauri', 'icons')
|
||||
os.makedirs(OUT, exist_ok=True)
|
||||
|
||||
BRAND = (48, 86, 211)
|
||||
BRAND_DARK = (35, 62, 160)
|
||||
|
||||
def make(size):
|
||||
ss = size * 4 # 超采样抗锯齿
|
||||
img = Image.new('RGBA', (ss, ss), (0, 0, 0, 0))
|
||||
d = ImageDraw.Draw(img)
|
||||
radius = ss // 5
|
||||
# 背景圆角方块(上浅下深的纵向渐变)
|
||||
grad = Image.new('RGBA', (ss, ss), (0, 0, 0, 0))
|
||||
gd = ImageDraw.Draw(grad)
|
||||
for y in range(ss):
|
||||
t = y / ss
|
||||
c = tuple(int(BRAND[i] + (BRAND_DARK[i] - BRAND[i]) * t) for i in range(3)) + (255,)
|
||||
gd.line([(0, y), (ss, y)], fill=c)
|
||||
mask = Image.new('L', (ss, ss), 0)
|
||||
md = ImageDraw.Draw(mask)
|
||||
md.rounded_rectangle([0, 0, ss - 1, ss - 1], radius=radius, fill=255)
|
||||
img.paste(grad, (0, 0), mask)
|
||||
# 抽象足迹:前掌大椭圆 + 后跟小椭圆
|
||||
white = (255, 255, 255, 240)
|
||||
d.ellipse([ss*0.24, ss*0.16, ss*0.60, ss*0.62], fill=white) # 前掌
|
||||
d.ellipse([ss*0.56, ss*0.58, ss*0.86, ss*0.84], fill=(255, 255, 255, 200)) # 后跟
|
||||
return img.resize((size, size), Image.LANCZOS)
|
||||
|
||||
for name, size in [('32x32.png', 32), ('128x128.png', 128), ('128x128@2x.png', 256), ('icon.png', 512)]:
|
||||
make(size).save(os.path.join(OUT, name))
|
||||
|
||||
ico_sizes = [16, 24, 32, 48, 64, 128, 256]
|
||||
imgs = [make(s) for s in ico_sizes]
|
||||
imgs[-1].save(os.path.join(OUT, 'icon.ico'), format='ICO', sizes=[(s, s) for s in ico_sizes])
|
||||
print('icons generated:', os.listdir(OUT))
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
from PIL import Image, ImageDraw
|
||||
import os
|
||||
|
||||
OUT = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'app', 'public', 'icons')
|
||||
os.makedirs(OUT, exist_ok=True)
|
||||
BRAND = (48, 86, 211)
|
||||
BRAND_DARK = (35, 62, 160)
|
||||
|
||||
def make(size, safe=1.0):
|
||||
ss = size * 4
|
||||
img = Image.new('RGBA', (ss, ss), (0, 0, 0, 0))
|
||||
grad = Image.new('RGBA', (ss, ss), (0, 0, 0, 0))
|
||||
gd = ImageDraw.Draw(grad)
|
||||
for y in range(ss):
|
||||
t = y / ss
|
||||
c = tuple(int(BRAND[i] + (BRAND_DARK[i] - BRAND[i]) * t) for i in range(3)) + (255,)
|
||||
gd.line([(0, y), (ss, y)], fill=c)
|
||||
mask = Image.new('L', (ss, ss), 0)
|
||||
ImageDraw.Draw(mask).rounded_rectangle([0, 0, ss - 1, ss - 1], radius=ss // 5, fill=255)
|
||||
img.paste(grad, (0, 0), mask)
|
||||
d = ImageDraw.Draw(img)
|
||||
white = (255, 255, 255, 240)
|
||||
# safe 缩放:maskable 时内容收缩到中心 70% 区域
|
||||
cx, cy, k = ss / 2, ss / 2, safe
|
||||
d.ellipse([cx - 0.18*ss*k, cy - 0.34*ss*k, cx + 0.18*ss*k, cy + 0.10*ss*k], fill=white)
|
||||
d.ellipse([cx + 0.03*ss*k, cy + 0.08*ss*k, cx + 0.33*ss*k, cy + 0.34*ss*k], fill=(255, 255, 255, 200))
|
||||
return img.resize((size, size), Image.LANCZOS)
|
||||
|
||||
make(192).save(os.path.join(OUT, 'pwa-192.png'))
|
||||
make(512).save(os.path.join(OUT, 'pwa-512.png'))
|
||||
make(512, safe=0.7).save(os.path.join(OUT, 'maskable-512.png'))
|
||||
print('pwa icons:', os.listdir(OUT))
|
||||
Reference in New Issue
Block a user