diff --git a/src/ImageProcessor/Samplers/ImageSampleExtensions.cs b/src/ImageProcessor/Samplers/ImageSampleExtensions.cs index 9b560c9ea..88ed3ef68 100644 --- a/src/ImageProcessor/Samplers/ImageSampleExtensions.cs +++ b/src/ImageProcessor/Samplers/ImageSampleExtensions.cs @@ -66,6 +66,7 @@ namespace ImageProcessor.Samplers /// The target image width. /// The target image height. /// The + /// Passing zero for one of height or width will automatically preserve the aspect ratio of the original image public static Image Resize(this Image source, int width, int height) { return Resize(source, width, height, new RobidouxResampler()); @@ -79,6 +80,7 @@ namespace ImageProcessor.Samplers /// The target image height. /// The to perform the resampling. /// The + /// Passing zero for one of height or width will automatically preserve the aspect ratio of the original image public static Image Resize(this Image source, int width, int height, IResampler sampler) { return Resize(source, width, height, sampler, source.Bounds); @@ -96,8 +98,18 @@ namespace ImageProcessor.Samplers /// The structure that specifies the portion of the image object to draw. /// /// The + /// Passing zero for one of height or width will automatically preserve the aspect ratio of the original image public static Image Resize(this Image source, int width, int height, IResampler sampler, Rectangle sourceRectangle) { + if (width == 0 && height > 0) + { + width = source.Width * height / source.Height; + } + if (height == 0 && width > 0) + { + height = source.Height * width / source.Width; + } + return source.Process(width, height, sourceRectangle, new Rectangle(0, 0, width, height), new Resampler(sampler)); } diff --git a/tests/ImageProcessor.Tests/Processors/Samplers/SamplerTests.cs b/tests/ImageProcessor.Tests/Processors/Samplers/SamplerTests.cs index a525c84d4..8cebfabbb 100644 --- a/tests/ImageProcessor.Tests/Processors/Samplers/SamplerTests.cs +++ b/tests/ImageProcessor.Tests/Processors/Samplers/SamplerTests.cs @@ -65,6 +65,62 @@ } } + [Fact] + public void ImageShouldResizeWidthAndKeepAspect() + { + if (!Directory.Exists("TestOutput/Resize")) + { + Directory.CreateDirectory("TestOutput/Resize"); + } + + var name = "FixedWidth"; + + foreach (string file in Files) + { + using (FileStream stream = File.OpenRead(file)) + { + Stopwatch watch = Stopwatch.StartNew(); + Image image = new Image(stream); + string filename = Path.GetFileNameWithoutExtension(file) + "-" + name + Path.GetExtension(file); + using (FileStream output = File.OpenWrite($"TestOutput/Resize/{filename}")) + { + image.Resize(image.Width / 3, 0, new TriangleResampler()) + .Save(output); + } + + Trace.WriteLine($"{name}: {watch.ElapsedMilliseconds}ms"); + } + } + } + + [Fact] + public void ImageShouldResizeHeightAndKeepAspect() + { + if (!Directory.Exists("TestOutput/Resize")) + { + Directory.CreateDirectory("TestOutput/Resize"); + } + + var name = "FixedHeight"; + + foreach (string file in Files) + { + using (FileStream stream = File.OpenRead(file)) + { + Stopwatch watch = Stopwatch.StartNew(); + Image image = new Image(stream); + string filename = Path.GetFileNameWithoutExtension(file) + "-" + name + Path.GetExtension(file); + using (FileStream output = File.OpenWrite($"TestOutput/Resize/{filename}")) + { + image.Resize(0, image.Height / 3, new TriangleResampler()) + .Save(output); + } + + Trace.WriteLine($"{name}: {watch.ElapsedMilliseconds}ms"); + } + } + } + [Theory] [MemberData("RotateFlips")] public void ImageShouldRotateFlip(RotateType rotateType, FlipType flipType)