-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathImageUtils.cs
163 lines (132 loc) · 6.16 KB
/
ImageUtils.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
using Microsoft.Extensions.Caching.Memory;
using SkiaSharp;
namespace EasyFortniteStats_ImageApi;
public class ImageUtils
{
public static void BitmapPostEvictionCallback(object key, object? value, EvictionReason reason, object? state)
{
Console.WriteLine($"MemoryCache: Disposing {key} | Reason: {reason}");
if (value is null) return;
var bmp = (SKBitmap) value;
bmp.Dispose();
}
public static async Task<SKBitmap> GenerateDiscordBox(SharedAssets _assets, string username,
float resizeFactor = 1.0f)
{
var segoeFont = await _assets.GetFont("Assets/Fonts/Segoe.ttf"); // don't dispose
using var discordTagTextPaint = new SKPaint();
discordTagTextPaint.IsAntialias = true;
discordTagTextPaint.Color = SKColors.White;
discordTagTextPaint.Typeface = segoeFont;
discordTagTextPaint.TextSize = 25 * resizeFactor;
var discordTagTextBounds = new SKRect();
discordTagTextPaint.MeasureText(username, ref discordTagTextBounds);
var imageInfo = new SKImageInfo(
(int) Math.Min(discordTagTextBounds.Width + (10 + 2 * 15 + 50) * resizeFactor, 459 * resizeFactor),
(int) (62 * resizeFactor));
var bitmap = new SKBitmap(imageInfo);
using var canvas = new SKCanvas(bitmap);
var discordBoxR = 15 * resizeFactor;
using var discordBoxPaint = new SKPaint();
discordBoxPaint.IsAntialias = true;
discordBoxPaint.Color = new SKColor(88, 101, 242);
canvas.DrawRoundRect(0, 0, imageInfo.Width, imageInfo.Height, discordBoxR, discordBoxR, discordBoxPaint);
var logoResizeWidth = (int) (50 * resizeFactor);
var discordLogoBitmap = await _assets.GetBitmap("Assets/Images/DiscordLogo.png"); // don't dispose
// get height with the same aspect ratio
var logoResizeHeight = (int) (discordLogoBitmap!.Height * (logoResizeWidth / (float) discordLogoBitmap.Width));
var discordLogoBitmapResized =
discordLogoBitmap.Resize(new SKImageInfo(logoResizeWidth, logoResizeHeight), SKFilterQuality.High);
canvas.DrawBitmap(discordLogoBitmapResized, 10 * resizeFactor,
(float) (imageInfo.Height - discordLogoBitmapResized.Height) / 2);
while (discordTagTextBounds.Width + (10 + 2 * 15 + 50) * resizeFactor > imageInfo.Width)
{
discordTagTextPaint.TextSize--;
discordTagTextPaint.MeasureText(username, ref discordTagTextBounds);
}
canvas.DrawText(username, (10 + 15) * resizeFactor + discordLogoBitmapResized.Width,
(float) imageInfo.Height / 2 - discordTagTextBounds.MidY, discordTagTextPaint);
return bitmap;
}
public static SKBitmap RotateBitmap(SKBitmap bitmap, float angle)
{
var radians = MathF.PI * angle / 180;
var sine = MathF.Abs(MathF.Sin(radians));
var cosine = MathF.Abs(MathF.Cos(radians));
int originalWidth = bitmap.Width, originalHeight = bitmap.Height;
var rotatedWidth = (int) (cosine * originalWidth + sine * originalHeight);
var rotatedHeight = (int) (cosine * originalHeight + sine * originalWidth);
var rotatedBitmap = new SKBitmap(rotatedWidth, rotatedHeight);
using var rotatedCanvas = new SKCanvas(rotatedBitmap);
rotatedCanvas.Clear();
rotatedCanvas.Translate(rotatedWidth / 2f, rotatedHeight / 2f);
rotatedCanvas.RotateDegrees(-angle);
rotatedCanvas.Translate(-originalWidth / 2f, -originalHeight / 2f);
rotatedCanvas.DrawBitmap(bitmap, SKPoint.Empty);
return rotatedBitmap;
}
public static SKBitmap GenerateRarityStripe(int width, SKColor rarityColor)
{
var imageInfo = new SKImageInfo(width, 14);
var bitmap = new SKBitmap(imageInfo);
using var canvas = new SKCanvas(bitmap);
using var paint = new SKPaint();
{
paint.IsAntialias = true;
paint.Color = rarityColor;
paint.Style = SKPaintStyle.Fill;
using var path = new SKPath();
path.MoveTo(0, imageInfo.Height - 5);
path.LineTo(imageInfo.Width, 0);
path.LineTo(imageInfo.Width, imageInfo.Height - 6);
path.LineTo(0, imageInfo.Height);
path.Close();
canvas.DrawPath(path, paint);
}
return bitmap;
}
public static SKBitmap GenerateItemCardOverlay(int width, SKBitmap? icon = null)
{
var imageInfo = new SKImageInfo(width, 65);
var bitmap = new SKBitmap(imageInfo);
using var canvas = new SKCanvas(bitmap);
using (var paint = new SKPaint())
{
paint.IsAntialias = true;
paint.Color = new SKColor(14, 14, 14);
paint.Style = SKPaintStyle.Fill;
canvas.DrawRect(0, 0, imageInfo.Width, imageInfo.Height, paint);
}
if (icon is not null)
{
using var rotatedVbucksBitmap = RotateBitmap(icon, -20);
using var resizedVBucksBitmap = rotatedVbucksBitmap.Resize(new SKImageInfo(47, 47), SKFilterQuality.Medium);
canvas.DrawBitmap(resizedVBucksBitmap, new SKPoint(imageInfo.Width - 45, imageInfo.Height - 35));
}
using (var paint = new SKPaint())
{
paint.IsAntialias = true;
paint.Color = new SKColor(30, 30, 30);
paint.Style = SKPaintStyle.Fill;
using var path = new SKPath();
path.MoveTo(0, imageInfo.Height - 29);
path.LineTo(imageInfo.Width, imageInfo.Height - 29);
path.LineTo(imageInfo.Width, imageInfo.Height - 25);
path.LineTo(0, imageInfo.Height - 24);
path.Close();
canvas.DrawPath(path, paint);
canvas.DrawRect(0, 0, imageInfo.Width, imageInfo.Height - 29, paint);
}
return bitmap;
}
public static SKColor ParseColor(string hexString)
{
var span = hexString.AsSpan();
var offset = span[0] == '#' ? 1 : 0;
if (hexString.Length - offset == 8)
{
hexString = string.Concat(span.Slice(6 + offset, 2), span.Slice(0 + offset, 6));
}
return SKColor.Parse(hexString);
}
}