From 31d8c345f574391721ffb300b41cd7dc402af718 Mon Sep 17 00:00:00 2001 From: SpoinkyNL Date: Fri, 23 Oct 2020 19:22:11 +0200 Subject: [PATCH] Color quantizer - Encapsulation & code style --- .../Artemis.Core.csproj.DotSettings | 2 + .../ColorQuantizer/ColorQuantizerService.cs | 70 ++++++++++--------- src/Artemis.sln.DotSettings | 3 +- 3 files changed, 42 insertions(+), 33 deletions(-) diff --git a/src/Artemis.Core/Artemis.Core.csproj.DotSettings b/src/Artemis.Core/Artemis.Core.csproj.DotSettings index 790b5129b..06398867e 100644 --- a/src/Artemis.Core/Artemis.Core.csproj.DotSettings +++ b/src/Artemis.Core/Artemis.Core.csproj.DotSettings @@ -50,6 +50,8 @@ True True True + True + True True True True diff --git a/src/Artemis.Core/Services/ColorQuantizer/ColorQuantizerService.cs b/src/Artemis.Core/Services/ColorQuantizer/ColorQuantizerService.cs index 3463010ba..394811006 100644 --- a/src/Artemis.Core/Services/ColorQuantizer/ColorQuantizerService.cs +++ b/src/Artemis.Core/Services/ColorQuantizer/ColorQuantizerService.cs @@ -1,13 +1,28 @@ -using SkiaSharp; -using System; +using System; using System.Collections.Generic; using System.Linq; +using SkiaSharp; namespace Artemis.Core.Services { /// - public class ColorQuantizerService : IColorQuantizerService + internal class ColorQuantizerService : IColorQuantizerService { + private static float GetComparisonValue(float sat, float targetSaturation, float luma, float targetLuma) + { + static float InvertDiff(float value, float target) + { + return 1 - Math.Abs(value - target); + } + + const float totalWeight = weightSaturation + weightLuma; + + float totalValue = InvertDiff(sat, targetSaturation) * weightSaturation + + InvertDiff(luma, targetLuma) * weightLuma; + + return totalValue / totalWeight; + } + /// public SKColor[] Quantize(IEnumerable colors, int amount) { @@ -20,7 +35,7 @@ namespace Artemis.Core.Services while (cubes.Count < amount) { ColorCube cube = cubes.Dequeue(); - if (cube.TrySplit(out var a, out var b)) + if (cube.TrySplit(out ColorCube? a, out ColorCube? b)) { cubes.Enqueue(a); cubes.Enqueue(b); @@ -30,22 +45,6 @@ namespace Artemis.Core.Services return cubes.Select(c => c.GetAverageColor()).ToArray(); } - #region Constants - private const float targetDarkLuma = 0.26f; - private const float maxDarkLuma = 0.45f; - private const float minLightLuma = 0.55f; - private const float targetLightLuma = 0.74f; - private const float minNormalLuma = 0.3f; - private const float targetNormalLuma = 0.5f; - private const float maxNormalLuma = 0.7f; - private const float targetMutesSaturation = 0.3f; - private const float maxMutesSaturation = 0.3f; - private const float targetVibrantSaturation = 1.0f; - private const float minVibrantSaturation = 0.35f; - private const float weightSaturation = 3f; - private const float weightLuma = 5f; - #endregion - /// public SKColor FindColorVariation(IEnumerable colors, ColorType type, bool ignoreLimits = false) { @@ -60,9 +59,9 @@ namespace Artemis.Core.Services _ => (0.5f, 0f, 1f, 0.5f, 0f, 1f) }; - var bestColorScore = float.MinValue; - var bestColor = SKColor.Empty; - foreach (var clr in colors) + float bestColorScore = float.MinValue; + SKColor bestColor = SKColor.Empty; + foreach (SKColor clr in colors) { clr.ToHsl(out float _, out float sat, out float luma); sat /= 100f; @@ -71,7 +70,7 @@ namespace Artemis.Core.Services if (!ignoreLimits && (sat <= minSaturation || sat >= maxSaturation || luma <= minLuma || luma >= maxLuma)) continue; - var score = GetComparisonValue(sat, targetSaturation, luma, targetLuma); + float score = GetComparisonValue(sat, targetSaturation, luma, targetLuma); if (score > bestColorScore) { bestColorScore = score; @@ -82,15 +81,22 @@ namespace Artemis.Core.Services return bestColor; } - private static float GetComparisonValue(float sat, float targetSaturation, float luma, float targetLuma) - { - static float InvertDiff(float value, float target) => 1 - Math.Abs(value - target); - const float totalweight = weightSaturation + weightLuma; + #region Constants - float totalValue = (InvertDiff(sat, targetSaturation) * weightSaturation) + - (InvertDiff(luma, targetLuma) * weightLuma); + private const float targetDarkLuma = 0.26f; + private const float maxDarkLuma = 0.45f; + private const float minLightLuma = 0.55f; + private const float targetLightLuma = 0.74f; + private const float minNormalLuma = 0.3f; + private const float targetNormalLuma = 0.5f; + private const float maxNormalLuma = 0.7f; + private const float targetMutesSaturation = 0.3f; + private const float maxMutesSaturation = 0.3f; + private const float targetVibrantSaturation = 1.0f; + private const float minVibrantSaturation = 0.35f; + private const float weightSaturation = 3f; + private const float weightLuma = 5f; - return totalValue / totalweight; - } + #endregion } } \ No newline at end of file diff --git a/src/Artemis.sln.DotSettings b/src/Artemis.sln.DotSettings index 1e1dea0e3..8a6f2fb99 100644 --- a/src/Artemis.sln.DotSettings +++ b/src/Artemis.sln.DotSettings @@ -213,4 +213,5 @@ True True True - True \ No newline at end of file + True + True \ No newline at end of file