Files
ykxmz/_build/render_watch_preview.py
T
xmz7891 b705216e4a ykxmz 1.5.0锛氫慨澶嶆墜琛ㄧ TLS 璇佷功鏍¢獙 + MTU 淇缃戠粶绋冲畾鎬?
琚帶绔?- 淇 MTU 闂锛氬す MSS + 璺緞 MTU 鎺㈡祴锛堝叕缃戝彲鐢ㄧ巼 48% -> 100%锛?- 澶嶇敤 HTTP 杩炴帴锛堝厤鎺夋瘡娆℃柊寤?TLS 鐨?30% 鎻℃墜澶辫触锛?- 姣忓垎閽熷洖澶存壘灞€鍩熺綉锛岃嚜鍔ㄥ垏鍥炲揩 400 鍊嶇殑璺緞
- 鐢婚潰蹇冭烦甯э細闈欐鏃剁渷娴侀噺锛屽鎴风浠嶇煡閬撴祦鏄椿鐨?- 閿佸睆鏃剁粰鍑哄彲鎿嶄綔鐨勬彁绀?
鎵嬭〃绔?- 鍐呯疆 GTS Root R4 / GlobalSign Root CA锛屼慨 SSLHandshakeException
- 杩炴帴閿欒缈昏瘧鎴愪汉璇濓紙璇佷功/鏃堕棿/瑙f瀽/瓒呮椂鍒嗗埆鎻愮ず锛?- 缁忎腑杞繛涓婂悗鐢ㄦ湇鍔″櫒鎶ョ殑鍦板潃鍒锋柊宸查厤瀵硅褰?- 鏂板灞€鍩熺綉杩炴帴椤甸潰銆佹湇鍔″櫒寤惰繜妫€娴?
鏈嶅姟鍣ㄧ
- 鏀寔 chunked 璇锋眰浣擄紙淇瘡 16 绉掍竴娆$殑杩炴帴閿欎贡涓庡ぇ闈㈢Н 502锛?- 缃戠粶璋冧紭鑴氭湰 net-tune.sh锛堝紑鏈鸿嚜鍔ㄥ簲鐢級
- 绠$悊椤碉細鎵归噺鍒犻櫎銆佺綉缁滀綋妫€銆佷笅杞藉尯
- 闅ч亾鏀?HTTP/2 + 鍙岃繛鎺?
鏂囨。
- 璁稿彲鍗忚 / 瀹夎鍓嶅繀璇?/ 瀹夎鍚庨』鐭ワ紙浣滆€咃細灏忛害瀛愶級
2026-10-06 19:01:05 +08:00

261 lines
10 KiB
Python

# -*- coding: utf-8 -*-
"""渲染手表端「液态玻璃」UI 预览图。
不是真机截图,是按 492x602 / density 1.4125 的真实参数用 Pillow 画的
设计预览。视觉按 MainActivity 里的实际实现来:
背景 斜向三段渐变(浅蓝 → 浅紫 → 浅粉)
玻璃 白色 70% + 1dp 亮边 + 圆角 18dp
高光 每块玻璃顶部一条更亮的渐变,模拟反光
Tab 玻璃容器 + 一个会滑过去的蓝色胶囊指示器
"""
from __future__ import annotations
import sys
from pathlib import Path
from PIL import Image, ImageDraw, ImageFilter, ImageFont
# ---- 与 MainActivity 一致的配色 ----
C_FG = (0x1F, 0x23, 0x28)
C_ACCENT = (0x18, 0x5C, 0xE8)
C_OK = (0x1A, 0x7F, 0x37)
C_DANGER = (0xCF, 0x22, 0x2E)
C_DIM = (0x65, 0x6D, 0x76)
GLASS_BG_TOP = (0xE8, 0xF0, 0xFF)
GLASS_BG_MID = (0xF1, 0xEB, 0xFF)
GLASS_BG_BOT = (0xFF, 0xF0, 0xF6)
GLASS_ALPHA = 0.70
GLASS_EDGE_ALPHA = 0.60
WIDTH_PX = 492
HEIGHT_PX = 602
DENSITY = 1.4125
TABS = [
("媒体", ["播放/暂停", "停止", "上一曲", "下一曲", "音量 +", "音量 -", "静音"]),
("屏幕", ["屏幕镜像", "截屏", "投图到电脑", "放音到电脑", "关显示器", "设为壁纸"]),
("文件", ["发送文件", "接收文件", "剪贴板→电脑", "取电脑剪贴板", "剪贴板历史", "打开文件夹"]),
("语音", ["语音播报", "音色", "朗读剪贴板", "电脑音乐", "弹通知"]),
("电脑", ["快捷命令", "打开网址", "进程管理", "性能", "磁盘", "电量"]),
("系统", ["锁屏", "睡眠", "关机", "重启", "取消定时关机", "定时关机", "设备诊断"]),
("功能", ["显示", "音量", "系统", "查看", "效率", "教学", "网络", "文件", "工具", "媒体"]),
("娱乐", ["全屏弹幕", "滚动字幕", "抽奖", "掷骰子", "抛硬币", "3-2-1", "影院模式",
"随机放歌", "播放视频", "计分板", "改分数", "加油动画"]),
("极客", ["数字雨", "星空穿梭", "全屏监控", "生成二维码", "算哈希", "Base64 编码",
"Base64 解码", "生成 UUID", "时间戳", "JSON 格式化", "鼠标取色", "网络测速",
"端口检查"]),
]
FONTS = [r"C:\Windows\Fonts\msyh.ttc", r"C:\Windows\Fonts\msyhbd.ttc",
r"C:\Windows\Fonts\simhei.ttf"]
def font(px: int):
for path in FONTS:
if Path(path).is_file():
try:
return ImageFont.truetype(path, px)
except Exception:
continue
return ImageFont.load_default()
def dp(value: float) -> int:
return int(round(value * DENSITY))
def gradient_background(width: int, height: int) -> Image.Image:
"""斜向三段渐变(先画小的再放大,省时间也够平滑)。"""
small_w, small_h = 96, 96
small = Image.new("RGB", (small_w, small_h))
pixels = small.load()
stops = [GLASS_BG_TOP, GLASS_BG_MID, GLASS_BG_BOT]
for y in range(small_h):
for x in range(small_w):
t = (x / (small_w - 1) + y / (small_h - 1)) / 2.0
scaled = t * (len(stops) - 1)
index = min(int(scaled), len(stops) - 2)
local = scaled - index
a, b = stops[index], stops[index + 1]
pixels[x, y] = tuple(
int(a[i] + (b[i] - a[i]) * local) for i in range(3))
return small.resize((width, height), Image.BICUBIC)
def glass_panel(base: Image.Image, box, radius, fill_alpha=GLASS_ALPHA,
tint=None, edge_alpha=GLASS_EDGE_ALPHA):
"""在 base 上叠一块玻璃:白色半透明 + 亮边 + 顶部高光。"""
x0, y0, x1, y1 = box
width, height = max(1, x1 - x0), max(1, y1 - y0)
overlay = Image.new("RGBA", (width, height), (0, 0, 0, 0))
draw = ImageDraw.Draw(overlay)
base_color = tint if tint else (255, 255, 255)
alpha = int(255 * fill_alpha)
draw.rounded_rectangle([0, 0, width - 1, height - 1], radius=radius,
fill=(base_color[0], base_color[1], base_color[2], alpha))
# 顶部高光:越靠上越亮
highlight = Image.new("RGBA", (width, height), (0, 0, 0, 0))
hdraw = ImageDraw.Draw(highlight)
for i in range(min(height, radius * 2)):
strength = int(38 * (1 - i / max(1, radius * 2)))
hdraw.line([(0, i), (width, i)], fill=(255, 255, 255, strength))
mask = Image.new("L", (width, height), 0)
ImageDraw.Draw(mask).rounded_rectangle([0, 0, width - 1, height - 1],
radius=radius, fill=255)
overlay = Image.alpha_composite(overlay, Image.composite(
highlight, Image.new("RGBA", (width, height), (0, 0, 0, 0)), mask))
# 亮边
draw = ImageDraw.Draw(overlay)
draw.rounded_rectangle([0, 0, width - 1, height - 1], radius=radius,
outline=(255, 255, 255, int(255 * edge_alpha)), width=1)
base.alpha_composite(overlay, (x0, y0))
def render_tab(tab_index: int, name: str, labels: list) -> Image.Image:
img = gradient_background(WIDTH_PX, HEIGHT_PX).convert("RGBA")
d = ImageDraw.Draw(img)
f_title = font(dp(12))
f_tab = font(dp(12))
f_btn = font(dp(11))
f_small = font(dp(9))
pad = dp(8)
y = pad
# ---- 顶栏 ----
bar_h = dp(38)
glass_panel(img, (pad, y, WIDTH_PX - pad, y + bar_h), dp(16))
d = ImageDraw.Draw(img)
d.ellipse([pad + dp(9), y + bar_h // 2 - dp(3),
pad + dp(15), y + bar_h // 2 + dp(3)], fill=C_OK)
d.text((pad + dp(20), y + bar_h // 2), "DESKTOP-RN5I625",
font=f_title, fill=C_FG, anchor="lm")
d.text((pad + dp(20), y + bar_h // 2 + dp(7)), "192.168.2.64",
font=font(dp(7)), fill=C_DIM, anchor="lm")
bw = dp(58)
glass_panel(img, (WIDTH_PX - pad - dp(6) - bw, y + dp(5),
WIDTH_PX - pad - dp(6), y + bar_h - dp(5)), dp(11),
tint=C_DANGER, fill_alpha=0.92)
d = ImageDraw.Draw(img)
d.text((WIDTH_PX - pad - dp(6) - bw // 2, y + bar_h // 2), "断开",
font=f_btn, fill=(255, 255, 255), anchor="mm")
y += bar_h + dp(8)
# ---- Tab 栏(玻璃容器 + 滑动指示器)----
tab_h = dp(30)
glass_panel(img, (pad, y, WIDTH_PX - pad, y + tab_h + dp(6)), dp(18))
d = ImageDraw.Draw(img)
x = pad + dp(4)
indicator = None
for i, (tname, _items) in enumerate(TABS):
tw = dp(10) * len(tname) + dp(22)
if i == tab_index:
indicator = (x, y + dp(3), x + tw, y + dp(3) + tab_h)
x += tw
if indicator:
# 指示器:蓝色胶囊 + 顶部高光
ix0, iy0, ix1, iy1 = indicator
glass_panel(img, indicator, dp(14), tint=C_ACCENT, fill_alpha=0.94,
edge_alpha=0.45)
d = ImageDraw.Draw(img)
d = ImageDraw.Draw(img)
x = pad + dp(4)
right_limit = WIDTH_PX - pad - dp(4)
for i, (tname, _items) in enumerate(TABS):
tw = dp(10) * len(tname) + dp(22)
if x + tw > right_limit:
break
on = (i == tab_index)
d.text((x + tw // 2, y + dp(3) + tab_h // 2), tname, font=f_tab,
fill=(255, 255, 255) if on else C_FG, anchor="mm")
x += tw
# 右边如果还有标签,画个渐隐提示可以滑
if x < right_limit:
for k in range(dp(14)):
alpha = int(200 * (1 - k / dp(14)))
d.line([(right_limit - dp(14) + k, y + dp(3)),
(right_limit - dp(14) + k, y + dp(3) + tab_h)],
fill=(0xEE, 0xEE, 0xF6, alpha))
y += tab_h + dp(18)
# ---- 按钮网格 ----
log_h = dp(48)
grid_bottom = HEIGHT_PX - pad - log_h - dp(8)
columns = 3
cell_h = dp(58)
gap = dp(5)
content_w = WIDTH_PX - pad * 2
cell_w = (content_w - gap * (columns - 1)) // columns
for index, label in enumerate(labels):
row = index // columns
col = index % columns
bx = pad + col * (cell_w + gap)
by = y + row * (cell_h + gap)
if by + cell_h > grid_bottom:
break
glass_panel(img, (bx, by, bx + cell_w, by + cell_h), dp(16))
d = ImageDraw.Draw(img)
text = label
if d.textlength(text, font=f_btn) > cell_w - dp(8):
while text and d.textlength(text + "…", font=f_btn) > cell_w - dp(8):
text = text[:-1]
text += "…"
d.text((bx + cell_w // 2, by + cell_h // 2), text, font=f_btn,
fill=C_FG, anchor="mm")
# ---- 日志 ----
log_top = HEIGHT_PX - pad - log_h
glass_panel(img, (pad, log_top, WIDTH_PX - pad, log_top + log_h), dp(14),
fill_alpha=0.82)
d = ImageDraw.Draw(img)
d.text((pad + dp(8), log_top + dp(8)), "[21:20] 已连接 192.168.2.64",
font=f_small, fill=C_DIM, anchor="lt")
d.text((pad + dp(8), log_top + dp(24)), "[21:20] 电脑端共 105 个功能",
font=f_small, fill=C_DIM, anchor="lt")
d.text((WIDTH_PX // 2, HEIGHT_PX - dp(1)),
f"设计预览(非真机截图)· 液态玻璃 · 分页「{name}」",
font=f_small, fill=C_DIM, anchor="mb")
return img.convert("RGB")
def main() -> int:
out_dir = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote\_build")
out_dir.mkdir(parents=True, exist_ok=True)
# 主展示页:媒体
media_index = 0
cover = render_tab(media_index, TABS[media_index][0], TABS[media_index][1])
cover.save(out_dir / "watch_preview.png")
print(f" 单页预览: {out_dir / 'watch_preview.png'}")
# 九页总览
tiles = [render_tab(i, n, l) for i, (n, l) in enumerate(TABS)]
scale = 0.46
tw, th = int(WIDTH_PX * scale), int(HEIGHT_PX * scale)
gap = 10
cols = 5
rows = (len(tiles) + cols - 1) // cols
total_w = tw * cols + gap * (cols + 1)
total_h = th * rows + gap * (rows + 1)
sheet = Image.new("RGB", (total_w, total_h), (0xE4, 0xE8, 0xF0))
for i, tile in enumerate(tiles):
row, col = divmod(i, cols)
sheet.paste(tile.resize((tw, th), Image.LANCZOS),
(gap + col * (tw + gap), gap + row * (th + gap)))
sheet.save(out_dir / "watch_preview_all.png")
print(f" 总览: {out_dir / 'watch_preview_all.png'} {sheet.size}")
return 0
if __name__ == "__main__":
sys.exit(main())