From 69699bcf89d203d9851bbeeb87b207c5a6043fb2 Mon Sep 17 00:00:00 2001 From: lifegpc Date: Sun, 10 Sep 2023 20:46:47 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=9B=BE=E6=A0=87=E9=A2=9C=E8=89=B2?= =?UTF-8?q?=E9=9A=8F=E5=9B=BE=E7=89=87=E4=BA=AE=E5=BA=A6=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/components/thumbnail.dart | 38 ++++++++++++++++++++++++++++++++++- pubspec.lock | 8 ++++++++ pubspec.yaml | 1 + 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/components/thumbnail.dart b/lib/components/thumbnail.dart index 897ac23..a45be7e 100644 --- a/lib/components/thumbnail.dart +++ b/lib/components/thumbnail.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:logging/logging.dart'; import 'package:path/path.dart'; +import 'package:palette_generator/palette_generator.dart'; import '../api/client.dart'; import '../api/gallery.dart'; import '../globals.dart'; @@ -61,6 +62,8 @@ class _Thumbnail extends State { CancelToken? _cancel; String? _fileName; String _dir = ""; + Color? _iconColor; + double? _iconSize; Future _fetchData() async { try { _cancel = CancelToken(); @@ -91,6 +94,7 @@ class _Thumbnail extends State { _data = data; _cancel = null; }); + updateIconColor(); } } catch (e) { if (!_cancel!.isCancelled) { @@ -117,6 +121,36 @@ class _Thumbnail extends State { super.initState(); } + Future updateIconColor() async { + if (_data == null) return; + try { + final img = await instantiateImageCodec(_data!); + try { + final frame = await img.getNextFrame(); + final i = frame.image; + try { + final iconSize = _iconSize ?? 24.0; + final pattle = await PaletteGenerator.fromImage(i, + region: Rect.fromCenter( + center: Offset(i.width / 2, i.height / 2), + width: iconSize, + height: iconSize)); + setState(() { + _iconColor = pattle.colors.first.computeLuminance() > 0.5 + ? Colors.black + : Colors.white; + }); + } finally { + i.dispose(); + } + } finally { + img.dispose(); + } + } catch (e) { + _log.warning("Failed to generate icon's color from image data:", e); + } + } + bool get showNsfw => _showNsfw || (prefs.getBool("showNsfw") ?? false); @override @@ -157,6 +191,7 @@ class _Thumbnail extends State { final isLoading = _data == null && _error == null; final isNsfw = widget._pMeta.isNsfw; if (isLoading && !_isLoading) _fetchData(); + _iconSize ??= Theme.of(context).iconTheme.size; final iconSize = MediaQuery.of(context).size.width < 400 ? 14.0 : Theme.of(context).iconTheme.size; @@ -215,7 +250,8 @@ class _Thumbnail extends State { _showNsfw = true; }); }, - icon: const Icon(Icons.visibility), + icon: Icon(Icons.visibility, + color: _iconColor ?? Colors.black), ), )), moreVertMenu diff --git a/pubspec.lock b/pubspec.lock index aa6f770..f7b6ed4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -518,6 +518,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.0" + palette_generator: + dependency: "direct main" + description: + name: palette_generator + sha256: eb7082b4b97487ebc65b3ad3f6f0b7489b96e76840381ed0e06a46fe7ffd4068 + url: "https://pub.dev" + source: hosted + version: "0.3.3+3" path: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 2ebfb7f..47ca16b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -28,6 +28,7 @@ dependencies: intl: any json_annotation: ^4.8.1 logging: ^1.2.0 + palette_generator: ^0.3.3+3 path: ^1.8.3 path_provider: ^2.1.0 retrofit: ^4.0.1