diff --git a/src/ImageProcessor/Samplers/ImageSampleExtensions.cs b/src/ImageProcessor/Samplers/ImageSampleExtensions.cs index 9b560c9ea2..88ed3ef68c 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 a525c84d40..8cebfabbba 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)