80 lines
2.9 KiB
Python
80 lines
2.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""gen_wallpaper.py — 生成 Win11 风格抽象壁纸(无需外部图片素材)
|
|
|
|
以深海军蓝渐变为底,叠加多层低透明度旋转椭圆"花瓣"光晕
|
|
(模拟 Win11 Bloom),四角轻微暗角。输出 wallpaper.png。
|
|
"""
|
|
import math
|
|
from PIL import Image, ImageDraw, ImageFilter
|
|
|
|
W, H = 1000, 700
|
|
|
|
def main():
|
|
# 底:垂直渐变 深蓝 #16264a → 暗蓝黑 #0a0e1c
|
|
base = Image.new("RGB", (W, H))
|
|
top = (22, 38, 74)
|
|
bot = (9, 13, 27)
|
|
px = base.load()
|
|
for y in range(H):
|
|
t = y / (H - 1)
|
|
r = int(top[0] * (1 - t) + bot[0] * t)
|
|
g = int(top[1] * (1 - t) + bot[1] * t)
|
|
b = int(top[2] * (1 - t) + bot[2] * t)
|
|
for x in range(W):
|
|
px[x, y] = (r, g, b)
|
|
|
|
# Bloom 花瓣层:中心偏右上的多层旋转椭圆光晕
|
|
glow = Image.new("RGBA", (W, H), (0, 0, 0, 0))
|
|
gd = ImageDraw.Draw(glow)
|
|
cx, cy = W * 0.58, H * 0.44
|
|
petals = [
|
|
# (长半轴, 短半轴, 角度deg, 颜色, alpha)
|
|
(300, 130, 15, (86, 130, 220), 46),
|
|
(260, 100, -25, (110, 90, 200), 40),
|
|
(230, 80, 50, (60, 170, 220), 36),
|
|
(200, 70, -60, (140, 110, 230), 32),
|
|
(170, 60, 85, (70, 200, 190), 30),
|
|
(150, 55, -100, (170, 130, 240), 26),
|
|
(330, 150, 30, (60, 100, 190), 22),
|
|
(140, 50, 120, (90, 150, 240), 24),
|
|
]
|
|
for rx, ry, ang, col, alpha in petals:
|
|
layer = Image.new("RGBA", (W, H), (0, 0, 0, 0))
|
|
ld = ImageDraw.Draw(layer)
|
|
# 椭圆边界框(绕中心旋转后取包围盒,再由 rotate 转正)
|
|
bbox = [cx - rx, cy - ry, cx + rx, cy + ry]
|
|
ld.ellipse(bbox, fill=col + (alpha,))
|
|
layer = layer.rotate(ang, center=(cx, cy), resample=Image.BICUBIC)
|
|
glow = Image.alpha_composite(glow, layer)
|
|
|
|
# 大光晕柔化后叠加
|
|
glow = glow.filter(ImageFilter.GaussianBlur(28))
|
|
out = Image.alpha_composite(base.convert("RGBA"), glow)
|
|
|
|
# 暗角:四角压暗(径向 alpha 蒙版)
|
|
vign = Image.new("L", (W, H), 0)
|
|
vd = ImageDraw.Draw(vign)
|
|
steps = 24
|
|
for i in range(steps):
|
|
t = i / steps
|
|
# 由外向内画黑色环带,alpha 递减
|
|
shrink = int((1 - t) * 260)
|
|
alpha = int(70 * (1 - t) ** 2)
|
|
vd.ellipse([-shrink, -shrink, W + shrink, H + shrink],
|
|
outline=(alpha,), width=int(260 / steps) + 2)
|
|
dark = Image.new("RGBA", (W, H), (0, 0, 0, 255))
|
|
dark.putalpha(vign)
|
|
out = Image.alpha_composite(out, dark)
|
|
|
|
out.convert("RGB").save("wallpaper.png")
|
|
# 嵌入位图来源:PNG(人看)+ 原始 RGBA(裸机加载,无解码器)。
|
|
# 注意:不能用 PIL 直接 save(".rgba")——该扩展被 SgiImagePlugin 认领,
|
|
# 会写 512 字节 SGI 头。必须手写 tobytes()。
|
|
with open("wallpaper.rgba", "wb") as f:
|
|
f.write(out.convert("RGBA").tobytes())
|
|
print("wallpaper.png/.rgba generated:", W, "x", H)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|