29 lines
1.2 KiB
Dart
29 lines
1.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:palette_generator/palette_generator.dart';
|
|
|
|
/// Extract a lively accent color from album art, mirroring Timbre's
|
|
/// art-driven `dynamic` theme (`color.rs`): pick the most vibrant swatch, then
|
|
/// nudge it into a readable lightness/saturation band. Timbre does the boost in
|
|
/// OKLab; this HSL approximation is close enough for now (OKLab is a later
|
|
/// refinement noted in the roadmap).
|
|
Future<Color?> extractAccent(ImageProvider image) async {
|
|
final palette = await PaletteGenerator.fromImageProvider(
|
|
image,
|
|
size: const Size(200, 200),
|
|
maximumColorCount: 8,
|
|
);
|
|
|
|
final picked = palette.vibrantColor?.color ??
|
|
palette.lightVibrantColor?.color ??
|
|
palette.dominantColor?.color;
|
|
if (picked == null) return null;
|
|
return _ensureReadable(picked);
|
|
}
|
|
|
|
Color _ensureReadable(Color c) {
|
|
final hsl = HSLColor.fromColor(c);
|
|
// Keep it bright enough to read on near-black, saturated enough to feel alive.
|
|
final lightness = hsl.lightness.clamp(0.45, 0.70);
|
|
final saturation = hsl.saturation < 0.40 ? 0.55 : hsl.saturation;
|
|
return hsl.withLightness(lightness).withSaturation(saturation).toColor();
|
|
}
|