此版本包含多项功能优化与修复: 1. 新增鸿蒙分层图标生成脚本,完善鸿蒙应用图标适配 2. 重构多处FutureProvider为NotifierProvider,修复ElementWithFuture异常 3. 更新flutter_tts依赖为鸿蒙适配版本,调整pubspec配置 4. 优化运势卡片样式文案,更新引导页功能介绍详情 5. 修复在线TTS服务Path正则匹配问题,支持含点号的路径 6. 重构通知权限、崩溃监控等状态管理逻辑 7. 更新翻译覆盖率统计,支持手动标注真实翻译进度 8. 优化编辑器工具栏、会话流页面交互细节 9. 新增日志筛选、导出CSV等增强功能 10. 调整设置页面文案,优化用户操作体验
103 lines
3.2 KiB
Python
103 lines
3.2 KiB
Python
"""
|
||
鸿蒙分层图标生成脚本
|
||
创建时间: 2026-05-26
|
||
更新时间: 2026-05-26
|
||
作用: 从源图标生成鸿蒙分层图标(前景层 + 背景层 + layered_image.json)
|
||
上次更新: 前景层填充透明区域为主色调,消除边框,图标铺满占位
|
||
"""
|
||
|
||
import os
|
||
import json
|
||
from PIL import Image
|
||
|
||
SOURCE_ICON = "assets/templates/resized/icon_1024x1024.png"
|
||
OUTPUT_SIZE = 1024
|
||
|
||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||
SOURCE_PATH = os.path.join(BASE_DIR, SOURCE_ICON)
|
||
|
||
APPSCOPE_MEDIA = os.path.join(BASE_DIR, "ohos", "AppScope", "resources", "base", "media")
|
||
ENTRY_MEDIA = os.path.join(BASE_DIR, "ohos", "entry", "src", "main", "resources", "base", "media")
|
||
|
||
|
||
def sample_dominant_color(img: Image.Image) -> tuple:
|
||
px = img.load()
|
||
w, h = img.size
|
||
r_sum, g_sum, b_sum, count = 0, 0, 0, 0
|
||
for y in range(h):
|
||
for x in range(w):
|
||
r, g, b, a = px[x, y]
|
||
if a > 200:
|
||
r_sum += r
|
||
g_sum += g
|
||
b_sum += b
|
||
count += 1
|
||
if count == 0:
|
||
return (255, 255, 255)
|
||
return (r_sum // count, g_sum // count, b_sum // count)
|
||
|
||
|
||
def generate_background(bg_color: tuple, size: int) -> Image.Image:
|
||
return Image.new("RGBA", (size, size), (*bg_color, 255))
|
||
|
||
|
||
def generate_foreground(img: Image.Image, fill_color: tuple, size: int) -> Image.Image:
|
||
fg = img.convert("RGBA").resize((size, size), Image.LANCZOS)
|
||
filled = Image.new("RGBA", (size, size), (*fill_color, 255))
|
||
filled.paste(fg, (0, 0), fg)
|
||
return filled
|
||
|
||
|
||
def generate_layered_json() -> dict:
|
||
return {
|
||
"layered-image": {
|
||
"foreground": "$media:foreground_icon",
|
||
"background": "$media:background_icon"
|
||
}
|
||
}
|
||
|
||
|
||
def save_to_dirs(foreground: Image.Image, background: Image.Image, layered_json: dict):
|
||
dirs = [APPSCOPE_MEDIA, ENTRY_MEDIA]
|
||
for d in dirs:
|
||
os.makedirs(d, exist_ok=True)
|
||
fg_path = os.path.join(d, "foreground_icon.png")
|
||
bg_path = os.path.join(d, "background_icon.png")
|
||
json_path = os.path.join(d, "layered_image.json")
|
||
|
||
foreground.save(fg_path, "PNG")
|
||
background.save(bg_path, "PNG")
|
||
with open(json_path, "w", encoding="utf-8") as f:
|
||
json.dump(layered_json, f, indent=2, ensure_ascii=False)
|
||
|
||
fg_size = os.path.getsize(fg_path)
|
||
bg_size = os.path.getsize(bg_path)
|
||
print(f" {d}")
|
||
print(f" foreground: {fg_path} ({fg_size / 1024:.1f}KB)")
|
||
print(f" background: {bg_path} ({bg_size / 1024:.1f}KB)")
|
||
print(f" layered_image.json: {json_path}")
|
||
|
||
|
||
def main():
|
||
print(f"源图标: {SOURCE_PATH}")
|
||
if not os.path.exists(SOURCE_PATH):
|
||
print(f"错误: 源图标不存在: {SOURCE_PATH}")
|
||
return
|
||
|
||
img = Image.open(SOURCE_PATH)
|
||
print(f" 尺寸: {img.size}")
|
||
|
||
fill_color = sample_dominant_color(img)
|
||
print(f" 填充色(主色调): RGB{fill_color}")
|
||
|
||
background = generate_background(fill_color, OUTPUT_SIZE)
|
||
foreground = generate_foreground(img, fill_color, OUTPUT_SIZE)
|
||
layered_json = generate_layered_json()
|
||
|
||
save_to_dirs(foreground, background, layered_json)
|
||
print("\n完成!")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|