Files
Open-Archival/OpenArchival.DataAccess.FileAccessManager/ImageThumbnailer.cs
2026-05-17 20:54:09 -04:00

90 lines
3.1 KiB
C#

using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using OpenArchival.Blazor.CustomComponents;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
using System.IO;
namespace OpenArchival.DataAccess.FileAccessManager;
public class ImageThumbnailer : IImageThumbnailer
{
private readonly IOptions<FileUploadOptions> _fileUploadOptions;
private readonly ILogger<ImageThumbnailer> _logger;
private static readonly string[] SupportedExtensions = { ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp", ".tiff" };
public ImageThumbnailer(IOptions<FileUploadOptions> fileUploadOptions, ILogger<ImageThumbnailer> logger)
{
_fileUploadOptions = fileUploadOptions;
_logger = logger;
}
public async Task<ThumbnailResult> GenerateThumbnailsAsync(string originalFilePath)
{
if (!File.Exists(originalFilePath))
{
_logger.LogError("Original file not found: {Path}", originalFilePath);
throw new FileNotFoundException("Original file not found", originalFilePath);
}
if (!IsSupportedImage(originalFilePath))
{
_logger.LogWarning("File is not a supported image format: {Path}", originalFilePath);
return new ThumbnailResult(string.Empty, string.Empty);
}
var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(originalFilePath);
var thumbnailFolder = _fileUploadOptions.Value.ThumbnailFolderPath;
if (!Directory.Exists(thumbnailFolder))
{
Directory.CreateDirectory(thumbnailFolder);
}
var smallPath = Path.Combine(thumbnailFolder, $"{fileNameWithoutExtension}_small.webp");
var largePath = Path.Combine(thumbnailFolder, $"{fileNameWithoutExtension}_large.webp");
using (var image = await Image.LoadAsync(originalFilePath))
{
await Task.WhenAll(
CreateThumbnailAsync(image.Clone(x => { }), smallPath, _fileUploadOptions.Value.SmallThumbnailSize),
CreateThumbnailAsync(image.Clone(x => { }), largePath, _fileUploadOptions.Value.LargeThumbnailSize)
);
}
return new ThumbnailResult(smallPath, largePath);
}
public bool IsSupportedImage(string filePath)
{
var extension = Path.GetExtension(filePath).ToLowerInvariant();
return SupportedExtensions.Contains(extension);
}
private async Task CreateThumbnailAsync(Image image, string outputPath, int maxSize)
{
using (image)
{
int width, height;
if (image.Width > image.Height)
{
width = maxSize;
height = (int)((double)image.Height / image.Width * maxSize);
}
else
{
height = maxSize;
width = (int)((double)image.Width / image.Height * maxSize);
}
image.Mutate(x => x.Resize(new ResizeOptions
{
Size = new Size(width, height),
Mode = ResizeMode.Max
}));
await image.SaveAsWebpAsync(outputPath);
}
}
}