using SkiaSharp; namespace SteUp.Maui.Core.Services; public static class ImageThumb { public static async Task CreateThumbnailAsync( string inputPath, string outputPath, int maxSide = 320, int quality = 70, CancellationToken ct = default) { // Leggi bytes (meglio in async) var data = await File.ReadAllBytesAsync(inputPath, ct); using var codec = SKCodec.Create(new SKMemoryStream(data)); if (codec is null) throw new InvalidOperationException("Formato immagine non supportato o file corrotto."); // Decodifica var info = codec.Info; using var bitmap = SKBitmap.Decode(codec); if (bitmap is null) throw new InvalidOperationException("Impossibile decodificare l'immagine."); // Calcola resize mantenendo aspect ratio var w = bitmap.Width; var h = bitmap.Height; if (w <= 0 || h <= 0) throw new InvalidOperationException("Dimensioni immagine non valide."); var scale = (float)maxSide / Math.Max(w, h); if (scale > 1f) scale = 1f; // non ingrandire var newW = Math.Max(1, (int)Math.Round(w * scale)); var newH = Math.Max(1, (int)Math.Round(h * scale)); using var resized = bitmap.Resize(new SKImageInfo(newW, newH), SKFilterQuality.Medium); if (resized is null) throw new InvalidOperationException("Resize fallito."); using var image = SKImage.FromBitmap(resized); using var encoded = image.Encode(SKEncodedImageFormat.Jpeg, quality); Directory.CreateDirectory(Path.GetDirectoryName(outputPath)!); await using var fs = File.Open(outputPath, FileMode.Create, FileAccess.Write, FileShare.None); encoded.SaveTo(fs); await fs.FlushAsync(ct); } }