Iceshrimp.NET/Iceshrimp.Backend/Core/Helpers/IdenticonHelper.cs
2025-01-09 12:36:34 +01:00

120 lines
4.9 KiB
C#

using System.IO.Hashing;
using System.Text;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
namespace Iceshrimp.Backend.Core.Helpers;
public static class IdenticonHelper
{
public static async Task<Stream> GetIdenticonAsync(string id)
{
using var image = new Image<Rgb24>(Size, Size);
var random = new Random((int)XxHash32.HashToUInt32(Encoding.UTF8.GetBytes(id)));
var color = Colors[random.Next(0, Colors.Count - 1)];
var gradient = new LinearGradientBrush(new Point(0, 0), new Point(Size, Size), GradientRepetitionMode.None,
new ColorStop(0, color.start), new ColorStop(1, color.end));
image.Mutate(p => p.Fill(gradient));
var paint = new SolidBrush(Color.White);
var side = new bool[SideN, CellCount];
var center = new bool[CellCount];
for (var i = 0; i < SideN; i++)
{
for (var j = 0; j < CellCount; j++)
{
side[i, j] = random.Next(3) == 0;
}
}
for (var i = 0; i < CellCount; i++)
{
center[i] = random.Next(3) == 0;
}
for (var i = 0; i < CellCount; i++)
{
for (var j = 0; j < CellCount; j++)
{
var isXCenter = i == (CellCount - 1) / 2;
if (isXCenter && !center[j])
continue;
var isLeftSide = i < (CellCount - 1) / 2;
if (isLeftSide && !side[i, j])
continue;
var isRightSide = i > (CellCount - 1) / 2;
if (isRightSide && !side[SideN - (i - SideN), j])
continue;
var actualX = Margin + CellSize * i;
var actualY = Margin + CellSize * j;
image.Mutate(p => p.Fill(paint, new Rectangle(actualX, actualY, CellSize, CellSize)));
}
}
var stream = new MemoryStream();
await image.SaveAsPngAsync(stream);
stream.Seek(0, SeekOrigin.Begin);
return stream;
}
#region Color definitions & Constants
private const int Size = 160;
private const int Margin = Size / 4;
private const int CellCount = 5;
private const int CellCanvasSize = Size - Margin * 2;
private const int CellSize = CellCanvasSize / CellCount;
private const int SideN = CellCount / 2;
private static readonly List<(Color start, Color end)> Colors =
[
(new Color(new Rgb24(235, 111, 146)), new Color(new Rgb24(180, 99, 122))),
(new Color(new Rgb24(246, 193, 119)), new Color(new Rgb24(234, 157, 52))),
(new Color(new Rgb24(235, 188, 186)), new Color(new Rgb24(215, 130, 126))),
(new Color(new Rgb24(156, 207, 216)), new Color(new Rgb24(86, 148, 159))),
(new Color(new Rgb24(196, 167, 231)), new Color(new Rgb24(144, 122, 169))),
(new Color(new Rgb24(235, 111, 146)), new Color(new Rgb24(246, 193, 119))),
(new Color(new Rgb24(235, 111, 146)), new Color(new Rgb24(235, 188, 186))),
(new Color(new Rgb24(235, 111, 146)), new Color(new Rgb24(49, 116, 143))),
(new Color(new Rgb24(235, 111, 146)), new Color(new Rgb24(156, 207, 216))),
(new Color(new Rgb24(235, 111, 146)), new Color(new Rgb24(196, 167, 231))),
(new Color(new Rgb24(246, 193, 119)), new Color(new Rgb24(235, 111, 146))),
(new Color(new Rgb24(246, 193, 119)), new Color(new Rgb24(235, 188, 186))),
(new Color(new Rgb24(246, 193, 119)), new Color(new Rgb24(49, 116, 143))),
(new Color(new Rgb24(246, 193, 119)), new Color(new Rgb24(156, 207, 216))),
(new Color(new Rgb24(246, 193, 119)), new Color(new Rgb24(196, 167, 231))),
(new Color(new Rgb24(235, 188, 186)), new Color(new Rgb24(235, 111, 146))),
(new Color(new Rgb24(235, 188, 186)), new Color(new Rgb24(246, 193, 119))),
(new Color(new Rgb24(235, 188, 186)), new Color(new Rgb24(49, 116, 143))),
(new Color(new Rgb24(235, 188, 186)), new Color(new Rgb24(156, 207, 216))),
(new Color(new Rgb24(235, 188, 186)), new Color(new Rgb24(196, 167, 231))),
(new Color(new Rgb24(49, 116, 143)), new Color(new Rgb24(235, 111, 146))),
(new Color(new Rgb24(49, 116, 143)), new Color(new Rgb24(246, 193, 119))),
(new Color(new Rgb24(49, 116, 143)), new Color(new Rgb24(235, 188, 186))),
(new Color(new Rgb24(49, 116, 143)), new Color(new Rgb24(156, 207, 216))),
(new Color(new Rgb24(49, 116, 143)), new Color(new Rgb24(196, 167, 231))),
(new Color(new Rgb24(156, 207, 216)), new Color(new Rgb24(235, 111, 146))),
(new Color(new Rgb24(156, 207, 216)), new Color(new Rgb24(246, 193, 119))),
(new Color(new Rgb24(156, 207, 216)), new Color(new Rgb24(235, 188, 186))),
(new Color(new Rgb24(156, 207, 216)), new Color(new Rgb24(49, 116, 143))),
(new Color(new Rgb24(156, 207, 216)), new Color(new Rgb24(196, 167, 231))),
(new Color(new Rgb24(196, 167, 231)), new Color(new Rgb24(235, 111, 146))),
(new Color(new Rgb24(196, 167, 231)), new Color(new Rgb24(246, 193, 119))),
(new Color(new Rgb24(196, 167, 231)), new Color(new Rgb24(235, 188, 186))),
(new Color(new Rgb24(196, 167, 231)), new Color(new Rgb24(49, 116, 143))),
(new Color(new Rgb24(196, 167, 231)), new Color(new Rgb24(156, 207, 216)))
];
#endregion
}