// 生成托盘图标(32x32 PNG) // dart run tool/gen_tray_icon.dart // - assets/tray_icon_template.png:macOS template 图标(纯黑+alpha,系统按菜单栏深浅自动反色) // - assets/tray_icon_win.png:Windows 彩色图标(绿底+深色卡片剪影) import 'dart:io'; import 'package:image/image.dart'; final _black = ColorRgba8(0, 0, 0, 255); final _green = ColorRgba8(74, 222, 128, 255); // 主操作绿 #4ADE80 final _navy = ColorRgba8(15, 23, 42, 255); // 深蓝黑 #0F172A bool _inRoundRect(int x, int y, int x0, int y0, int x1, int y1, int r) { if (x < x0 || x > x1 || y < y0 || y > y1) return false; final nearLeft = x < x0 + r, nearRight = x > x1 - r; final nearTop = y < y0 + r, nearBottom = y > y1 - r; if (!(nearLeft || nearRight) || !(nearTop || nearBottom)) return true; // 十字区 final cx = nearLeft ? x0 + r : x1 - r; final cy = nearTop ? y0 + r : y1 - r; final dx = x - cx, dy = y - cy; return dx * dx + dy * dy <= r * r; } /// 卡片剪影(含磁条挖空)画到 img 上 void _drawCard(Image img, int x0, int y0, int x1, int y1, ColorUint8 color) { const r = 2; final stripeY0 = y0 + (y1 - y0 + 1) ~/ 3; final stripeY1 = stripeY0 + 2; for (var y = y0; y <= y1; y++) { for (var x = x0; x <= x1; x++) { if (!_inRoundRect(x, y, x0, y0, x1, y1, r)) continue; if (y >= stripeY0 && y <= stripeY1) continue; // 磁条挖空 img.setPixel(x, y, color); } } } void main() { // macOS template:透明底 + 黑卡片 final mac = Image(width: 32, height: 32, numChannels: 4); _drawCard(mac, 5, 8, 26, 23, _black); // Windows:绿色圆角底 + 深色卡片 final win = Image(width: 32, height: 32, numChannels: 4); for (var y = 1; y <= 30; y++) { for (var x = 1; x <= 30; x++) { if (_inRoundRect(x, y, 1, 1, 30, 30, 6)) win.setPixel(x, y, _green); } } _drawCard(win, 7, 9, 24, 22, _navy); for (final entry in [('assets/tray_icon_template.png', mac), ('assets/tray_icon_win.png', win)]) { final file = File(entry.$1); file.parent.createSync(recursive: true); file.writeAsBytesSync(encodePng(entry.$2)); // ignore: avoid_print print('written ${entry.$1}'); } }