From e3cd896c394efa86ebbc406b798a784c96b77269 Mon Sep 17 00:00:00 2001 From: Alwin Drenth Date: Thu, 17 Mar 2022 16:37:18 +0100 Subject: [PATCH] Add "fill-max" resizing option --- docs/1.0/api/size.md | 3 ++- src/Manipulators/Size.php | 24 +++++++++++++++++++++++- tests/Manipulators/SizeTest.php | 10 ++++++++-- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/docs/1.0/api/size.md b/docs/1.0/api/size.md index 84e51bcb..99b26e46 100644 --- a/docs/1.0/api/size.md +++ b/docs/1.0/api/size.md @@ -34,6 +34,7 @@ Sets how the image is fitted to its target dimensions. - `contain`: Default. Resizes the image to fit within the width and height boundaries without cropping, distorting or altering the aspect ratio. - `max`: Resizes the image to fit within the width and height boundaries without cropping, distorting or altering the aspect ratio, and will also not increase the size of the image if it is smaller than the output size. - `fill`: Resizes the image to fit within the width and height boundaries without cropping or distorting the image, and the remaining space is filled with the background color. The resulting image will match the constraining dimensions. +- `fill-max`: Resizes the image to fit within the width and height boundaries without cropping but with distorting/blurring the image if it's smaller. The finished image will have remaining space on either width or height (except if the aspect ratio of the new image is the same as the old image). The remaining space will be filled with the background color. The resulting image will match the constraining dimensions. - `stretch`: Stretches the image to fit the constraining dimensions exactly. The resulting image will fill the dimensions, and will not maintain the aspect ratio of the input image. - `crop`: Resizes the image to fill the width and height boundaries and crops any excess image data. The resulting image will match the width and height constraints without distorting the image. See the [crop](api/crop/) page for more information. @@ -41,4 +42,4 @@ Sets how the image is fitted to its target dimensions. ~~~ -[![© Photo Joel Reynolds](https://glide.herokuapp.com/1.0/kayaks.jpg?w=300&h=300&fit=stretch)](https://glide.herokuapp.com/1.0/kayaks.jpg?w=300&h=300&fit=stretch) \ No newline at end of file +[![© Photo Joel Reynolds](https://glide.herokuapp.com/1.0/kayaks.jpg?w=300&h=300&fit=stretch)](https://glide.herokuapp.com/1.0/kayaks.jpg?w=300&h=300&fit=stretch) diff --git a/src/Manipulators/Size.php b/src/Manipulators/Size.php index 82ac92da..896c9e17 100644 --- a/src/Manipulators/Size.php +++ b/src/Manipulators/Size.php @@ -117,7 +117,7 @@ public function getHeight() */ public function getFit() { - if (in_array($this->fit, ['contain', 'fill', 'max', 'stretch'], true)) { + if (in_array($this->fit, ['contain', 'fill', 'max', 'fill-max', 'stretch'], true)) { return $this->fit; } @@ -247,6 +247,10 @@ public function runResize(Image $image, $fit, $width, $height) return $this->runMaxResize($image, $width, $height); } + if ($fit === 'fill-max') { + return $this->runFillMaxResize($image, $width, $height); + } + if ('stretch' === $fit) { return $this->runStretchResize($image, $width, $height); } @@ -291,6 +295,24 @@ public function runMaxResize(Image $image, $width, $height) }); } + /** + * Perform fill-max resize image manipulation. + * + * @param Image $image The source image. + * @param int $width The width. + * @param int $height The height. + * + * @return Image The manipulated image. + */ + public function runFillMaxResize(Image $image, $width, $height) + { + $image = $image->resize($width, $height, function ($constraint) { + $constraint->aspectRatio(); + }); + + return $image->resizeCanvas($width, $height, 'center'); + } + /** * Perform fill resize image manipulation. * diff --git a/tests/Manipulators/SizeTest.php b/tests/Manipulators/SizeTest.php index 2ffd5c2e..acd5e99c 100644 --- a/tests/Manipulators/SizeTest.php +++ b/tests/Manipulators/SizeTest.php @@ -76,6 +76,7 @@ public function testGetFit() $this->assertSame('contain', $this->manipulator->setParams(['fit' => 'contain'])->getFit()); $this->assertSame('fill', $this->manipulator->setParams(['fit' => 'fill'])->getFit()); $this->assertSame('max', $this->manipulator->setParams(['fit' => 'max'])->getFit()); + $this->assertSame('fill-max', $this->manipulator->setParams(['fit' => 'fill-max'])->getFit()); $this->assertSame('stretch', $this->manipulator->setParams(['fit' => 'stretch'])->getFit()); $this->assertSame('crop', $this->manipulator->setParams(['fit' => 'crop'])->getFit()); $this->assertSame('contain', $this->manipulator->setParams(['fit' => 'invalid'])->getFit()); @@ -150,9 +151,9 @@ public function testRunResize() $mock->shouldReceive('width')->andReturn(100)->times(4); $mock->shouldReceive('height')->andReturn(100)->times(4); $mock->shouldReceive('crop')->andReturn($mock)->once(); - $mock->shouldReceive('resize')->with(100, 100, $this->callback)->andReturn($mock)->times(4); + $mock->shouldReceive('resize')->with(100, 100, $this->callback)->andReturn($mock)->times(5); $mock->shouldReceive('resize')->with(100, 100)->andReturn($mock)->once(); - $mock->shouldReceive('resizeCanvas')->with(100, 100, 'center')->andReturn($mock)->once(); + $mock->shouldReceive('resizeCanvas')->with(100, 100, 'center')->andReturn($mock)->times(2); }); $this->assertInstanceOf( @@ -170,6 +171,11 @@ public function testRunResize() $this->manipulator->runResize($image, 'max', 100, 100) ); + $this->assertInstanceOf( + 'Intervention\Image\Image', + $this->manipulator->runResize($image, 'fill-max', 100, 100) + ); + $this->assertInstanceOf( 'Intervention\Image\Image', $this->manipulator->runResize($image, 'stretch', 100, 100)