diff --git a/src/Controllers/HomeController.cs b/src/Controllers/HomeController.cs index 58ce235..3f4e108 100644 --- a/src/Controllers/HomeController.cs +++ b/src/Controllers/HomeController.cs @@ -106,15 +106,15 @@ public class HomeController : Controller } if (size is null) { - return File(Convert.FromBase64String(user.JpegPhoto), "image/jpeg"); + return File(Convert.FromBase64String(user.JpegPhoto), "image/webp"); } if (size is not null) { AdminSettingsModel adminSettingsModel = await adminSettingsModelTask; size = Math.Min((int)size, adminSettingsModel.MaxDownloadableUserImageSize); } - string encodedFile = ImageHelper.ResizeAndConvertToBase64(Convert.FromBase64String(user.JpegPhoto), size ?? 32); - return File(Convert.FromBase64String(encodedFile), "image/jpeg"); + byte[] encodedFile = ImageHelper.ResizeAndConvertToWebp(user.JpegPhoto, size ?? 32); + return File(encodedFile, "image/webp"); } diff --git a/src/Helpers/ImageHelper.cs b/src/Helpers/ImageHelper.cs index 75d15e4..adc5651 100644 --- a/src/Helpers/ImageHelper.cs +++ b/src/Helpers/ImageHelper.cs @@ -1,5 +1,4 @@ using SixLabors.ImageSharp; -using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Formats.Webp; using SixLabors.ImageSharp.Formats; @@ -7,36 +6,33 @@ namespace Berufsschule_HAM.Helpers; public static class ImageHelper { - public static string ResizeAndConvertToBase64(byte[] imageBytes, int size = 32) + public static Dictionary> ImageCache = []; + public static byte[] ResizeAndConvertToWebp(string imageString, int size = 32) { - using var inputStream = new MemoryStream(imageBytes); - - var decoderOptions = new DecoderOptions + if (ImageCache.TryGetValue(size, out Dictionary? sizeCache) + && sizeCache.TryGetValue(imageString, out byte[]? result) && result.Length > 0) { - TargetSize = new Size(size, size) - }; - - using var image = Image.Load(decoderOptions, inputStream); - - int minDimension = Math.Min(image.Width, image.Height); - var cropRectangle = new Rectangle( - (image.Width - minDimension) / 2, - (image.Height - minDimension) / 2, - minDimension, - minDimension); - - image.Mutate(x => + return result; + } + if (sizeCache is null) ImageCache[size] = []; + lock (ImageCache[size]) { - x.Crop(cropRectangle); - x.Resize(new ResizeOptions + byte[] imageBytes = Convert.FromBase64String(imageString); + using var inputStream = new MemoryStream(imageBytes); + + var decoderOptions = new DecoderOptions { - Size = new Size(size, size), - Mode = ResizeMode.Crop - }); - }); + TargetSize = new Size(size, size), + SkipMetadata = true + }; - using var outputStream = new MemoryStream(); - image.Save(outputStream, new WebpEncoder()); - return Convert.ToBase64String(outputStream.GetBuffer(), 0, (int)outputStream.Length); + using var image = Image.Load(decoderOptions, inputStream); + + using var outputStream = new MemoryStream(); + image.Save(outputStream, new WebpEncoder()); + result = outputStream.ToArray(); + ImageCache[size][imageString] = result; + } + return result; } } \ No newline at end of file diff --git a/src/Program.cs b/src/Program.cs index f952fd8..8096252 100644 --- a/src/Program.cs +++ b/src/Program.cs @@ -12,6 +12,7 @@ var builder = WebApplication.CreateBuilder(args); builder.Services.Configure(builder.Configuration.GetSection("Ldap")); builder.Services.AddLocalization(options => options.ResourcesPath = "Resources"); +builder.Services.AddResponseCaching(); builder.Services.AddControllersWithViews() .AddViewLocalization(Microsoft.AspNetCore.Mvc.Razor.LanguageViewLocationExpanderFormat.Suffix)