feat: 图标颜色随图片亮度调整

This commit is contained in:
2023-09-10 20:46:47 +08:00
parent f0cedcf8a4
commit 69699bcf89
3 changed files with 46 additions and 1 deletions

View File

@@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:path/path.dart'; import 'package:path/path.dart';
import 'package:palette_generator/palette_generator.dart';
import '../api/client.dart'; import '../api/client.dart';
import '../api/gallery.dart'; import '../api/gallery.dart';
import '../globals.dart'; import '../globals.dart';
@@ -61,6 +62,8 @@ class _Thumbnail extends State<Thumbnail> {
CancelToken? _cancel; CancelToken? _cancel;
String? _fileName; String? _fileName;
String _dir = ""; String _dir = "";
Color? _iconColor;
double? _iconSize;
Future<void> _fetchData() async { Future<void> _fetchData() async {
try { try {
_cancel = CancelToken(); _cancel = CancelToken();
@@ -91,6 +94,7 @@ class _Thumbnail extends State<Thumbnail> {
_data = data; _data = data;
_cancel = null; _cancel = null;
}); });
updateIconColor();
} }
} catch (e) { } catch (e) {
if (!_cancel!.isCancelled) { if (!_cancel!.isCancelled) {
@@ -117,6 +121,36 @@ class _Thumbnail extends State<Thumbnail> {
super.initState(); super.initState();
} }
Future<void> 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); bool get showNsfw => _showNsfw || (prefs.getBool("showNsfw") ?? false);
@override @override
@@ -157,6 +191,7 @@ class _Thumbnail extends State<Thumbnail> {
final isLoading = _data == null && _error == null; final isLoading = _data == null && _error == null;
final isNsfw = widget._pMeta.isNsfw; final isNsfw = widget._pMeta.isNsfw;
if (isLoading && !_isLoading) _fetchData(); if (isLoading && !_isLoading) _fetchData();
_iconSize ??= Theme.of(context).iconTheme.size;
final iconSize = MediaQuery.of(context).size.width < 400 final iconSize = MediaQuery.of(context).size.width < 400
? 14.0 ? 14.0
: Theme.of(context).iconTheme.size; : Theme.of(context).iconTheme.size;
@@ -215,7 +250,8 @@ class _Thumbnail extends State<Thumbnail> {
_showNsfw = true; _showNsfw = true;
}); });
}, },
icon: const Icon(Icons.visibility), icon: Icon(Icons.visibility,
color: _iconColor ?? Colors.black),
), ),
)), )),
moreVertMenu moreVertMenu

View File

@@ -518,6 +518,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.0" 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: path:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@@ -28,6 +28,7 @@ dependencies:
intl: any intl: any
json_annotation: ^4.8.1 json_annotation: ^4.8.1
logging: ^1.2.0 logging: ^1.2.0
palette_generator: ^0.3.3+3
path: ^1.8.3 path: ^1.8.3
path_provider: ^2.1.0 path_provider: ^2.1.0
retrofit: ^4.0.1 retrofit: ^4.0.1