using SixLabors.ImageSharp; using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Formats.Png; namespace DramaLing.Api.Services; public class ImageProcessingService : IImageProcessingService { private readonly ILogger _logger; public ImageProcessingService(ILogger logger) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } public async Task ResizeImageAsync(byte[] originalBytes, int targetWidth, int targetHeight) { try { _logger.LogInformation("Resizing image from {OriginalSize}KB to {TargetWidth}x{TargetHeight}", originalBytes.Length / 1024, targetWidth, targetHeight); using var image = Image.Load(originalBytes); _logger.LogDebug("Original image size: {Width}x{Height}", image.Width, image.Height); // 使用高品質的 Lanczos3 重採樣算法 image.Mutate(x => x.Resize(targetWidth, targetHeight, KnownResamplers.Lanczos3)); using var output = new MemoryStream(); // 使用 PNG 格式儲存,保持品質 await image.SaveAsPngAsync(output, new PngEncoder { CompressionLevel = PngCompressionLevel.Level6, // 平衡壓縮和品質 ColorType = PngColorType.Rgb }); var resizedBytes = output.ToArray(); _logger.LogInformation("Image resized successfully. New size: {NewSize}KB (reduction: {Reduction:P})", resizedBytes.Length / 1024, 1.0 - (double)resizedBytes.Length / originalBytes.Length); return resizedBytes; } catch (Exception ex) { _logger.LogError(ex, "Failed to resize image"); throw; } } public async Task OptimizeImageAsync(byte[] originalBytes, int quality = 85) { try { _logger.LogInformation("Optimizing image, original size: {OriginalSize}KB", originalBytes.Length / 1024); using var image = Image.Load(originalBytes); using var output = new MemoryStream(); // 針對例句圖的優化設定 await image.SaveAsPngAsync(output, new PngEncoder { CompressionLevel = PngCompressionLevel.Level9, // 最高壓縮 ColorType = PngColorType.Rgb, BitDepth = PngBitDepth.Bit8 }); var optimizedBytes = output.ToArray(); _logger.LogInformation("Image optimized successfully. New size: {NewSize}KB (reduction: {Reduction:P})", optimizedBytes.Length / 1024, 1.0 - (double)optimizedBytes.Length / originalBytes.Length); return optimizedBytes; } catch (Exception ex) { _logger.LogError(ex, "Failed to optimize image"); throw; } } }