90 lines
3.1 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|