76 lines
2.1 KiB
C#
76 lines
2.1 KiB
C#
using Avalonia.Media;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
|
|
namespace Toolkit.UI.Controls.Avalonia;
|
|
|
|
public class PersonPictureColourGenerator
|
|
{
|
|
private readonly float hue;
|
|
private readonly float saturation;
|
|
private readonly float lightness;
|
|
private const float minLightness = 0.2f;
|
|
private const float maxLightness = 0.8f;
|
|
|
|
public PersonPictureColourGenerator(float hue = 210,
|
|
float saturation = 0.8f,
|
|
float lightness = 0.6f)
|
|
{
|
|
this.hue = hue;
|
|
this.saturation = saturation;
|
|
this.lightness = lightness;
|
|
}
|
|
|
|
public Color Create(string input)
|
|
{
|
|
byte[] hashBytes = GetHash(input);
|
|
|
|
float h = (hashBytes[0] + hue) % 360;
|
|
float s = (hashBytes[1] / 255.0f) * saturation;
|
|
float l = EnsureNonExtremeLightness((hashBytes[2] / 255.0f) * lightness);
|
|
|
|
(byte r, byte g, byte b) = HslToRgb(h, s, l);
|
|
|
|
return Color.FromRgb(r, g, b);
|
|
}
|
|
|
|
private byte[] GetHash(string input) =>
|
|
SHA256.HashData(Encoding.UTF8.GetBytes(input));
|
|
|
|
private float EnsureNonExtremeLightness(float calculatedLightness) =>
|
|
calculatedLightness < minLightness ? minLightness : calculatedLightness > maxLightness ?
|
|
maxLightness : calculatedLightness;
|
|
|
|
private (byte r, byte g, byte b) HslToRgb(float h, float s, float l)
|
|
{
|
|
h /= 360;
|
|
float r, g, b;
|
|
|
|
if (s == 0)
|
|
{
|
|
r = g = b = l;
|
|
}
|
|
else
|
|
{
|
|
float q = l < 0.5f ? l * (1 + s) : l + s - l * s;
|
|
float p = 2 * l - q;
|
|
|
|
r = HueToRgb(p, q, h + 1.0f / 3.0f);
|
|
g = HueToRgb(p, q, h);
|
|
b = HueToRgb(p, q, h - 1.0f / 3.0f);
|
|
}
|
|
|
|
return ((byte)(r * 255), (byte)(g * 255), (byte)(b * 255));
|
|
}
|
|
|
|
private float HueToRgb(float p, float q, float t)
|
|
{
|
|
if (t < 0) t += 1;
|
|
if (t > 1) t -= 1;
|
|
if (t < 1.0f / 6.0f) return p + (q - p) * 6 * t;
|
|
if (t < 1.0f / 2.0f) return q;
|
|
if (t < 2.0f / 3.0f) return p + (q - p) * (2.0f / 3.0f - t) * 6;
|
|
return p;
|
|
}
|
|
}
|