From afa86daac422a25baaa6843fb17e044da73f7e5f Mon Sep 17 00:00:00 2001 From: Oliver Vogel Date: Thu, 11 Nov 2021 14:11:01 +0000 Subject: [PATCH] Resizing --- src/Drivers/Abstract/AbstractImage.php | 32 +++++++---- src/Geometry/Resizer.php | 17 ++++-- src/Geometry/Size.php | 39 +++++++++++++ tests/Geometry/ResizerTest.php | 2 + tests/Geometry/SizeTest.php | 80 ++++++++++++++++++++++++++ 5 files changed, 154 insertions(+), 16 deletions(-) diff --git a/src/Drivers/Abstract/AbstractImage.php b/src/Drivers/Abstract/AbstractImage.php index 447de89c..9949a07f 100644 --- a/src/Drivers/Abstract/AbstractImage.php +++ b/src/Drivers/Abstract/AbstractImage.php @@ -169,21 +169,23 @@ abstract class AbstractImage ->scaleDown($crop); return $this->modify( - $this->resolveDriverClass('Modifiers\CropResizeModifier', $size) + $this->resolveDriverClass('Modifiers\CropResizeModifier', $crop, $resize) ); } public function fit(int $width, int $height, string $position = 'center'): ImageInterface { - // crop - $crop = Resizer::make() - ->toSize($this->getSize()) - ->contain(new Size($width, $height)); - $crop = Resizer::make() - ->toSize($crop) - ->crop($this->getSize(), $position); + $imagesize = $this->getSize(); - $resize = new Size($width, $height); + // crop + $crop = new Size($width, $height); + $crop = $crop->contain($imagesize)->alignPivotTo( + $imagesize->alignPivot($position), + $position + ); + + // resize + $resize = $crop->scale($width, $height); return $this->modify( $this->resolveDriverClass('Modifiers\CropResizeModifier', $crop, $resize, $position) @@ -192,7 +194,17 @@ abstract class AbstractImage public function fitDown(int $width, int $height, string $position = 'center'): ImageInterface { - $size = new Size($width, $height); + $imagesize = $this->getSize(); + + // crop + $crop = new Size($width, $height); + $crop = $crop->contain($imagesize)->alignPivotTo( + $imagesize->alignPivot($position), + $position + ); + + // resize + $resize = $crop->scaleDown($width, $height); return $this->modify( $this->resolveDriverClass('Modifiers\CropResizeModifier', $crop, $resize, $position) diff --git a/src/Geometry/Resizer.php b/src/Geometry/Resizer.php index 5b35f366..e704314b 100644 --- a/src/Geometry/Resizer.php +++ b/src/Geometry/Resizer.php @@ -2,6 +2,7 @@ namespace Intervention\Image\Geometry; +use Intervention\Image\Geometry\Size; use Intervention\Image\Interfaces\SizeInterface; /* @@ -120,6 +121,10 @@ class Resizer return $this; } + if (isset($arguments[0]) && is_a($arguments[0], Size::class)) { + return $this->toSize($arguments[0]); + } + if (isset($arguments[0]) && is_numeric($arguments[0])) { $this->width($arguments[0]); } @@ -163,7 +168,7 @@ class Resizer public function resize(SizeInterface $size): SizeInterface { - $resized = clone $size; + $resized = new Size($size->getWidth(), $size->getHeight()); if ($this->hasTargetWidth()) { $resized->setWidth($this->target->getWidth()); @@ -178,7 +183,7 @@ class Resizer public function resizeDown(SizeInterface $size): SizeInterface { - $resized = clone $size; + $resized = new Size($size->getWidth(), $size->getHeight()); if ($this->hasTargetWidth()) { $resized->setWidth( @@ -197,7 +202,7 @@ class Resizer public function scale(SizeInterface $size): SizeInterface { - $resized = clone $size; + $resized = new Size($size->getWidth(), $size->getHeight()); if ($this->hasTargetWidth() && $this->hasTargetHeight()) { $resized->setWidth(min( @@ -221,7 +226,7 @@ class Resizer public function scaleDown(SizeInterface $size): SizeInterface { - $resized = clone $size; + $resized = new Size($size->getWidth(), $size->getHeight()); if ($this->hasTargetWidth() && $this->hasTargetHeight()) { $resized->setWidth(min( @@ -265,7 +270,7 @@ class Resizer */ public function cover(SizeInterface $size): SizeInterface { - $resized = clone $size; + $resized = new Size($size->getWidth(), $size->getHeight()); // auto height $resized->setWidth($this->target->getWidth()); @@ -288,7 +293,7 @@ class Resizer */ public function contain(SizeInterface $size): SizeInterface { - $resized = clone $size; + $resized = new Size($size->getWidth(), $size->getHeight()); // auto height $resized->setWidth($this->target->getWidth()); diff --git a/src/Geometry/Size.php b/src/Geometry/Size.php index 18f6a8e3..3f4e76a4 100644 --- a/src/Geometry/Size.php +++ b/src/Geometry/Size.php @@ -2,6 +2,7 @@ namespace Intervention\Image\Geometry; +use Intervention\Image\Geometry\Resizer; use Intervention\Image\Interfaces\PointInterface; use Intervention\Image\Interfaces\SizeInterface; @@ -210,4 +211,42 @@ class Size implements SizeInterface return new Point($x, $y); } + + protected function getResizer(...$arguments): Resizer + { + $resizer = new Resizer(); + $resizer->setTargetSizeByArray($arguments[0]); + + return $resizer; + } + + public function resize(...$arguments): self + { + return $this->getResizer($arguments)->resize($this); + } + + public function resizeDown(...$arguments): self + { + return $this->getResizer($arguments)->resizeDown($this); + } + + public function scale(...$arguments): self + { + return $this->getResizer($arguments)->scale($this); + } + + public function scaleDown(...$arguments): self + { + return $this->getResizer($arguments)->scaleDown($this); + } + + public function cover(...$arguments): self + { + return $this->getResizer($arguments)->cover($this); + } + + public function contain(...$arguments): self + { + return $this->getResizer($arguments)->contain($this); + } } diff --git a/tests/Geometry/ResizerTest.php b/tests/Geometry/ResizerTest.php index fbe237ad..70ec340a 100644 --- a/tests/Geometry/ResizerTest.php +++ b/tests/Geometry/ResizerTest.php @@ -392,6 +392,7 @@ class ResizerTest extends TestCase [new Size(800, 600), new Size(800, 600), new Size(800, 600)], [new Size(400, 300), new Size(120, 120), new Size(160, 120)], [new Size(600, 800), new Size(100, 100), new Size(100, 133)], + [new Size(100, 100), new Size(800, 600), new Size(800, 800)], ]; } @@ -418,6 +419,7 @@ class ResizerTest extends TestCase [new Size(800, 600), new Size(800, 600), new Size(800, 600)], [new Size(400, 300), new Size(120, 120), new Size(120, 90)], [new Size(600, 800), new Size(100, 100), new Size(75, 100)], + [new Size(100, 100), new Size(800, 600), new Size(600, 600)], ]; } diff --git a/tests/Geometry/SizeTest.php b/tests/Geometry/SizeTest.php index 4551d28d..024bdf52 100644 --- a/tests/Geometry/SizeTest.php +++ b/tests/Geometry/SizeTest.php @@ -236,4 +236,84 @@ class SizeTest extends TestCase $this->assertEquals(0, $pos->getX()); $this->assertEquals(50, $pos->getY()); } + + public function testResize(): void + { + $size = new Size(300, 200); + $result = $size->resize(120, 150); + $this->assertInstanceOf(Size::class, $result); + + $size = new Size(300, 200); + $result = $size->resize(function ($resizer) { + $resizer->toWidth(100); + }); + $this->assertInstanceOf(Size::class, $result); + } + + public function testResizeDown(): void + { + $size = new Size(300, 200); + $result = $size->resizeDown(120, 150); + $this->assertInstanceOf(Size::class, $result); + + $size = new Size(300, 200); + $result = $size->resizeDown(function ($resizer) { + $resizer->toWidth(100); + }); + $this->assertInstanceOf(Size::class, $result); + } + + public function testScale(): void + { + $size = new Size(300, 200); + $result = $size->scale(120, 150); + $this->assertInstanceOf(Size::class, $result); + + $size = new Size(300, 200); + $result = $size->scale(function ($resizer) { + $resizer->toWidth(100); + }); + $this->assertInstanceOf(Size::class, $result); + } + + public function testScaleDown(): void + { + $size = new Size(300, 200); + $result = $size->scaleDown(120, 150); + $this->assertInstanceOf(Size::class, $result); + + $size = new Size(300, 200); + $result = $size->scaleDown(function ($resizer) { + $resizer->toWidth(100); + }); + $this->assertInstanceOf(Size::class, $result); + } + + public function testCover(): void + { + $size = new Size(300, 200); + $result = $size->cover(120, 150); + $this->assertInstanceOf(Size::class, $result); + + $size = new Size(300, 200); + $result = $size->cover(function ($resizer) { + $resizer->toWidth(100); + }); + $this->assertInstanceOf(Size::class, $result); + } + + public function testContain(): void + { + $size = new Size(100, 100); + $result = $size->contain(800, 600); + $this->assertInstanceOf(Size::class, $result); + $this->assertEquals(600, $result->getWidth()); + $this->assertEquals(600, $result->getHeight()); + + $size = new Size(300, 200); + $result = $size->contain(function ($resizer) { + $resizer->toWidth(100); + }); + $this->assertInstanceOf(Size::class, $result); + } }