Files
BetterLyrics/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/PaletteHelper.cs
Zhe Fang 4926fe55a3 chores:
- Add album text in lyrics render
- Improve song info update and draw algo
- Upgrade to .NET 10
2025-11-12 19:15:19 -05:00

81 lines
3.2 KiB
C#

using ColorThiefDotNet;
using Impressionist.Abstractions;
using Impressionist.Implementations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Threading.Tasks;
using Windows.Graphics.Imaging;
namespace BetterLyrics.WinUI3.Helper
{
public static class PaletteHelper
{
private static ColorThief colorThief = new();
public static async Task<PaletteResult> OctTreeGetAccentColorsFromByteAsync(BitmapDecoder decoder, int count, bool? isDark = null)
{
var colors = await GetPixelColor(decoder);
var palette = await PaletteGenerators.OctTreePaletteGenerator.CreatePalette(colors, count, false, isDark);
return palette;
}
public static async Task<ThemeColorResult> OctTreeGetAccentColorFromByteAsync(BitmapDecoder decoder)
{
var colors = await GetPixelColor(decoder);
var theme = await PaletteGenerators.OctTreePaletteGenerator.CreateThemeColor(colors, false);
return theme;
}
public static async Task<ThemeColorResult> MedianCutGetAccentColorFromByteAsync(BitmapDecoder decoder)
{
var mainColor = await colorThief.GetColor(decoder, 10, false);
var theme = new ThemeColorResult(new Vector3(mainColor.Color.R, mainColor.Color.G, mainColor.Color.B), mainColor.IsDark);
return theme;
}
public static async Task<PaletteResult> MedianCutGetAccentColorsFromByteAsync(BitmapDecoder decoder, int count, bool? isDark = null)
{
var mainColor = await colorThief.GetColor(decoder, 10, false);
var theme = new ThemeColorResult(new Vector3(mainColor.Color.R, mainColor.Color.G, mainColor.Color.B), mainColor.IsDark);
var palette = await colorThief.GetPalette(decoder, 255, 10, false);
var topColors = palette
.Where(x => x.IsDark == (isDark ?? mainColor.IsDark))
.OrderByDescending(x => x.Population)
.Select(x => new Vector3(x.Color.R, x.Color.G, x.Color.B))
.Take(count)
.ToList();
var paletteResult = new PaletteResult(topColors, mainColor.IsDark, theme);
return paletteResult;
}
public static async Task<Dictionary<Vector3, int>> GetPixelColor(BitmapDecoder bitmapDecoder)
{
var pixelDataProvider = await bitmapDecoder.GetPixelDataAsync();
var pixels = pixelDataProvider.DetachPixelData();
var count = bitmapDecoder.PixelWidth * bitmapDecoder.PixelHeight;
var vector = new Dictionary<Vector3, int>();
for (int i = 0; i < count; i += 10)
{
var offset = i * 4;
var b = pixels[offset];
var g = pixels[offset + 1];
var r = pixels[offset + 2];
var a = pixels[offset + 3];
if (a == 0) continue;
var color = new Vector3(r, g, b);
if (vector.ContainsKey(color))
{
vector[color]++;
}
else
{
vector[color] = 1;
}
}
return vector;
}
}
}