diff --git a/assets/icon/app_icon.png b/assets/icon/app_icon.png index 54c3dd6..fd73c39 100644 Binary files a/assets/icon/app_icon.png and b/assets/icon/app_icon.png differ diff --git a/assets/icon/app_icon_foreground.png b/assets/icon/app_icon_foreground.png index 54c3dd6..fd73c39 100644 Binary files a/assets/icon/app_icon_foreground.png and b/assets/icon/app_icon_foreground.png differ diff --git a/assets/icon/app_icon_ios.png b/assets/icon/app_icon_ios.png index c056e70..a8b28d9 100644 Binary files a/assets/icon/app_icon_ios.png and b/assets/icon/app_icon_ios.png differ diff --git a/assets/img/icon.png b/assets/img/icon.png index c056e70..a8b28d9 100644 Binary files a/assets/img/icon.png and b/assets/img/icon.png differ diff --git a/assets/img/icon_bg_removed.png b/assets/img/icon_bg_removed.png index 54c3dd6..fd73c39 100644 Binary files a/assets/img/icon_bg_removed.png and b/assets/img/icon_bg_removed.png differ diff --git a/assets/img/loadingScreenMainScreen.png b/assets/img/loadingScreenMainScreen.png index ea58e8a..e7a65b7 100644 Binary files a/assets/img/loadingScreenMainScreen.png and b/assets/img/loadingScreenMainScreen.png differ diff --git a/assets/img/login_bg.jpg b/assets/img/login_bg.jpg index ea58e8a..bd3ca7a 100644 Binary files a/assets/img/login_bg.jpg and b/assets/img/login_bg.jpg differ diff --git a/tool/optimize_assets.dart b/tool/optimize_assets.dart new file mode 100644 index 0000000..160973a --- /dev/null +++ b/tool/optimize_assets.dart @@ -0,0 +1,75 @@ +import 'dart:io'; +import 'package:image/image.dart' as img; + +class _AssetRule { + final String path; + final int maxDimension; + final int jpgQuality; + + const _AssetRule(this.path, {required this.maxDimension, this.jpgQuality = 86}); +} + +const _rules = <_AssetRule>[ + _AssetRule('assets/img/login_bg.jpg', maxDimension: 1920, jpgQuality: 84), + _AssetRule('assets/img/loadingScreenMainScreen.png', maxDimension: 1920), + _AssetRule('assets/img/icon.png', maxDimension: 1024), + _AssetRule('assets/img/icon_bg_removed.png', maxDimension: 1024), + _AssetRule('assets/icon/app_icon.png', maxDimension: 1024), + _AssetRule('assets/icon/app_icon_ios.png', maxDimension: 1024), + _AssetRule('assets/icon/app_icon_foreground.png', maxDimension: 1024), +]; + +void main() { + for (final rule in _rules) { + final file = File(rule.path); + if (!file.existsSync()) { + stdout.writeln('SKIP ${rule.path} (missing)'); + continue; + } + + final beforeBytes = file.lengthSync(); + final decoded = img.decodeImage(file.readAsBytesSync()); + if (decoded == null) { + stdout.writeln('SKIP ${rule.path} (decode failed)'); + continue; + } + + img.Image working = decoded; + final maxSide = working.width > working.height ? working.width : working.height; + + if (maxSide > rule.maxDimension) { + final scale = rule.maxDimension / maxSide; + final newWidth = (working.width * scale).round(); + final newHeight = (working.height * scale).round(); + working = img.copyResize( + working, + width: newWidth, + height: newHeight, + interpolation: img.Interpolation.average, + ); + } + + final lower = rule.path.toLowerCase(); + late final List encoded; + if (lower.endsWith('.jpg') || lower.endsWith('.jpeg')) { + encoded = img.encodeJpg(working, quality: rule.jpgQuality); + } else if (lower.endsWith('.png')) { + encoded = img.encodePng(working, level: 6); + } else { + stdout.writeln('SKIP ${rule.path} (unsupported type)'); + continue; + } + + file.writeAsBytesSync(encoded, flush: true); + final afterBytes = file.lengthSync(); + final saved = beforeBytes - afterBytes; + final pct = beforeBytes == 0 ? 0 : (saved / beforeBytes * 100); + + stdout.writeln( + 'DONE ${rule.path} ' + '${(beforeBytes / 1024).toStringAsFixed(1)}KB -> ' + '${(afterBytes / 1024).toStringAsFixed(1)}KB ' + '(${pct >= 0 ? '-' : '+'}${pct.abs().toStringAsFixed(1)}%)', + ); + } +}