145 lines
4.6 KiB
C#
145 lines
4.6 KiB
C#
using GozareshgirProgramManager.Application.Services.FileManagement;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.Extensions.Configuration;
|
|
using SixLabors.ImageSharp;
|
|
using SixLabors.ImageSharp.Processing;
|
|
using SixLabors.ImageSharp.Formats.Jpeg;
|
|
|
|
namespace GozareshgirProgramManager.Infrastructure.Services.FileManagement;
|
|
|
|
/// <summary>
|
|
/// سرویس تولید thumbnail با استفاده از ImageSharp
|
|
/// </summary>
|
|
public class ThumbnailGeneratorService : IThumbnailGeneratorService
|
|
{
|
|
private readonly string _thumbnailBasePath;
|
|
private readonly string _baseUrl;
|
|
|
|
public ThumbnailGeneratorService(IConfiguration configuration,
|
|
IHttpContextAccessor httpContextAccessor)
|
|
{
|
|
_thumbnailBasePath = configuration["FileStorage:ThumbnailPath"]
|
|
?? Path.Combine(Directory.GetCurrentDirectory(), "storage", "Thumbnails");
|
|
var request = httpContextAccessor.HttpContext?.Request;
|
|
|
|
if (request != null)
|
|
{
|
|
_baseUrl = $"{request.Scheme}://{request.Host}/storage";
|
|
}
|
|
else
|
|
{
|
|
_baseUrl = configuration["FileStorage:BaseUrl"] ?? "http://localhost:5000/storage";
|
|
}
|
|
|
|
if (!Directory.Exists(_thumbnailBasePath))
|
|
{
|
|
Directory.CreateDirectory(_thumbnailBasePath);
|
|
}
|
|
}
|
|
|
|
public async Task<(string ThumbnailPath, string ThumbnailUrl)?> GenerateImageThumbnailAsync(
|
|
string imagePath,
|
|
string category,
|
|
int width = 200,
|
|
int height = 200)
|
|
{
|
|
try
|
|
{
|
|
if (!File.Exists(imagePath))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
// بارگذاری تصویر
|
|
using var image = await Image.LoadAsync(imagePath);
|
|
|
|
// Resize با حفظ نسبت
|
|
image.Mutate(x => x.Resize(new ResizeOptions
|
|
{
|
|
Size = new Size(width, height),
|
|
Mode = ResizeMode.Max
|
|
}));
|
|
|
|
// نام فایل thumbnail
|
|
var fileName = Path.GetFileNameWithoutExtension(imagePath);
|
|
var extension = Path.GetExtension(imagePath);
|
|
var thumbnailFileName = $"{fileName}_thumb{extension}";
|
|
|
|
// دریافت مسیر و URL توسط متد private
|
|
var (thumbnailPath, thumbnailUrl) = GetThumbnailPathAndUrl(thumbnailFileName, category);
|
|
|
|
// ذخیره thumbnail با کیفیت 80
|
|
await image.SaveAsync(thumbnailPath, new JpegEncoder { Quality = 80 });
|
|
|
|
|
|
return (thumbnailPath, thumbnailUrl);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
// در صورت خطا null برمیگردانیم
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public async Task<(string ThumbnailPath, string ThumbnailUrl)?> GenerateVideoThumbnailAsync(string videoPath, string category = "general")
|
|
{
|
|
// TODO: برای Video thumbnail باید از FFmpeg استفاده کنیم
|
|
// فعلاً یک placeholder image برمیگردانیم
|
|
await Task.CompletedTask;
|
|
return null;
|
|
}
|
|
|
|
public Task DeleteThumbnailAsync(string thumbnailPath)
|
|
{
|
|
if (File.Exists(thumbnailPath))
|
|
{
|
|
File.Delete(thumbnailPath);
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public async Task<(int Width, int Height)?> GetImageDimensionsAsync(string imagePath)
|
|
{
|
|
try
|
|
{
|
|
if (!File.Exists(imagePath))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var imageInfo = await Image.IdentifyAsync(imagePath);
|
|
return (imageInfo.Width, imageInfo.Height);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// دریافت مسیر فیزیکی و URL برای thumbnail بر اساس category
|
|
/// </summary>
|
|
private (string ThumbnailPath, string ThumbnailUrl) GetThumbnailPathAndUrl(string thumbnailFileName, string category)
|
|
{
|
|
var categoryFolder = string.IsNullOrWhiteSpace(category) ? "general" : category;
|
|
var categoryPath = Path.Combine(Directory.GetCurrentDirectory(), "storage", categoryFolder);
|
|
|
|
if (!Directory.Exists(categoryPath))
|
|
{
|
|
Directory.CreateDirectory(categoryPath);
|
|
}
|
|
|
|
var thumbnailSubPath = Path.Combine(categoryPath, "Thumbnails");
|
|
if (!Directory.Exists(thumbnailSubPath))
|
|
{
|
|
Directory.CreateDirectory(thumbnailSubPath);
|
|
}
|
|
|
|
var thumbnailPath = Path.Combine(thumbnailSubPath, thumbnailFileName);
|
|
var thumbnailUrl = $"{_baseUrl}/{categoryFolder}/thumbnails/{thumbnailFileName}";
|
|
|
|
return (thumbnailPath, thumbnailUrl);
|
|
}
|
|
}
|