#if WINDOWS using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; namespace MeetingAssistant.Screenshots; internal sealed class WindowsScreenshotImageCropper : IScreenshotImageCropper { #pragma warning disable CA1416 public Task SaveCroppedScreenshotAsync( string screenshotPath, ScreenshotCropCoordinates crop, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); try { using var original = new Bitmap(screenshotPath); ValidateCrop(crop, original.Width, original.Height); var cropRectangle = new Rectangle(crop.X, crop.Y, crop.Width, crop.Height); using var cropped = original.Clone(cropRectangle, original.PixelFormat); var croppedPath = Path.Combine( Path.GetDirectoryName(screenshotPath)!, $"{Path.GetFileNameWithoutExtension(screenshotPath)}-cropped.png"); cropped.Save(croppedPath, ImageFormat.Png); return Task.FromResult(croppedPath); } catch (ExternalException exception) { throw new InvalidDataException( $"The screenshot crop {crop.X},{crop.Y},{crop.Width},{crop.Height} could not be applied.", exception); } } #pragma warning restore CA1416 private static void ValidateCrop( ScreenshotCropCoordinates crop, int imageWidth, int imageHeight) { if (crop.X < 0 || crop.Y < 0 || crop.Width <= 0 || crop.Height <= 0 || crop.X + crop.Width > imageWidth || crop.Y + crop.Height > imageHeight) { throw new InvalidDataException( $"Screenshot crop {crop.X},{crop.Y},{crop.Width},{crop.Height} is outside image bounds {imageWidth}x{imageHeight}."); } } } #endif