diff --git a/docs/image-manipulations/resizing-images.md b/docs/image-manipulations/resizing-images.md index b692be66..52f7e9bb 100644 --- a/docs/image-manipulations/resizing-images.md +++ b/docs/image-manipulations/resizing-images.md @@ -70,7 +70,7 @@ Resizes the image to fit within the width and height boundaries without cropping # Example of how to set background colour to fill remaining pixels $image - ->fit(fit: Fit::Fill, desiredWidth: 497, desiredHeight: 290, backgroundColor: '#ff5733'); + ->fit(fit: Fit::Fit::FillMax, desiredWidth: 497, desiredHeight: 290, backgroundColor: '#ff5733'); ``` ![Blue background on fit filled JPG](../../images/example-background.png) diff --git a/src/Drivers/Gd/GdDriver.php b/src/Drivers/Gd/GdDriver.php index ccda18d4..c68b98e2 100644 --- a/src/Drivers/Gd/GdDriver.php +++ b/src/Drivers/Gd/GdDriver.php @@ -22,6 +22,7 @@ use Spatie\Image\Enums\Orientation; use Spatie\Image\Exceptions\CouldNotLoadImage; use Spatie\Image\Exceptions\InvalidFont; +use Spatie\Image\Exceptions\MissingParameter; use Spatie\Image\Exceptions\UnsupportedImageFormat; use Spatie\Image\Point; use Spatie\Image\Size; @@ -236,6 +237,14 @@ public function fit( return $this->fitCrop($fit, $this->getWidth(), $this->getHeight(), $desiredWidth, $desiredHeight); } + if ($fit === Fit::FillMax) { + if (is_null($desiredWidth) || is_null($desiredHeight)) { + throw new MissingParameter('Both desiredWidth and desiredHeight must be set when using Fit::FillMax'); + } + + return $this->fitFillMax($desiredWidth, $desiredHeight, $backgroundColor); + } + $calculatedSize = $fit->calculateSize( $this->getWidth(), $this->getHeight(), @@ -259,6 +268,14 @@ public function fit( return $this; } + public function fitFillMax(int $desiredWidth, int $desiredHeight, string $backgroundColor, bool $relative = false): static + { + $this->resize($desiredWidth, $desiredHeight, [Constraint::PreserveAspectRatio]); + $this->resizeCanvas($desiredWidth, $desiredHeight, AlignPosition::Center, $relative, $backgroundColor); + + return $this; + } + protected function modify( int $desiredWidth, int $desiredHeight, diff --git a/src/Drivers/Imagick/ImagickDriver.php b/src/Drivers/Imagick/ImagickDriver.php index 92279dbd..75409036 100644 --- a/src/Drivers/Imagick/ImagickDriver.php +++ b/src/Drivers/Imagick/ImagickDriver.php @@ -22,6 +22,7 @@ use Spatie\Image\Enums\FlipDirection; use Spatie\Image\Enums\Orientation; use Spatie\Image\Exceptions\InvalidFont; +use Spatie\Image\Exceptions\MissingParameter; use Spatie\Image\Exceptions\UnsupportedImageFormat; use Spatie\Image\Point; use Spatie\Image\Size; @@ -131,6 +132,14 @@ public function fit( return $this->fitCrop($fit, $this->getWidth(), $this->getHeight(), $desiredWidth, $desiredHeight); } + if ($fit === Fit::FillMax) { + if (is_null($desiredWidth) || is_null($desiredHeight)) { + throw new MissingParameter('Both desiredWidth and desiredHeight must be set when using Fit::FillMax'); + } + + return $this->fitFillMax($desiredWidth, $desiredHeight, $backgroundColor); + } + $calculatedSize = $fit->calculateSize( $this->getWidth(), $this->getHeight(), @@ -149,6 +158,14 @@ public function fit( return $this; } + public function fitFillMax(int $desiredWidth, int $desiredHeight, string $backgroundColor, bool $relative = false): static + { + $this->resize($desiredWidth, $desiredHeight, [Constraint::PreserveAspectRatio]); + $this->resizeCanvas($desiredWidth, $desiredHeight, AlignPosition::Center, $relative, $backgroundColor); + + return $this; + } + public function resizeCanvas( ?int $width = null, ?int $height = null, diff --git a/src/Enums/Fit.php b/src/Enums/Fit.php index 03725e6e..a5a647b8 100644 --- a/src/Enums/Fit.php +++ b/src/Enums/Fit.php @@ -12,6 +12,8 @@ enum Fit: string case Stretch = 'stretch'; case Crop = 'crop'; + case FillMax = 'fill-max'; + public function calculateSize( int $originalWidth, int $originalHeight, @@ -25,7 +27,7 @@ public function calculateSize( $constraints = match ($this) { Fit::Contain => [Constraint::PreserveAspectRatio], - Fit::Fill, Fit::Max => [Constraint::PreserveAspectRatio, Constraint::DoNotUpsize], + Fit::Fill, Fit::Max, Fit::FillMax => [Constraint::PreserveAspectRatio, Constraint::DoNotUpsize], Fit::Stretch, Fit::Crop => [], }; @@ -34,6 +36,6 @@ public function calculateSize( public function shouldResizeCanvas(): bool { - return in_array($this, [self::Fill]); + return in_array($this, [self::Fill, self::FillMax]); } } diff --git a/src/Exceptions/MissingParameter.php b/src/Exceptions/MissingParameter.php new file mode 100644 index 00000000..a75ee4b9 --- /dev/null +++ b/src/Exceptions/MissingParameter.php @@ -0,0 +1,9 @@ +tempDir->path("{$driver->driverName()}/fit-background.png"); $driver->loadFile(getTestJpg()) - ->fit(fit: Fit::Fill, desiredWidth: 800, desiredHeight: 200, backgroundColor: '#0073ff') + ->fit(fit: Fit::FillMax, desiredWidth: 800, desiredHeight: 400, backgroundColor: '#0073ff') ->save($targetFile); assertMatchesImageSnapshot($targetFile); diff --git a/tests/__snapshots__/FitTest__it_can_fit_and_add_a_background_with_data_set_dataset_gd__1.png b/tests/__snapshots__/FitTest__it_can_fit_and_add_a_background_with_data_set_dataset_gd__1.png index 7fe886f9..062f2ac7 100644 Binary files a/tests/__snapshots__/FitTest__it_can_fit_and_add_a_background_with_data_set_dataset_gd__1.png and b/tests/__snapshots__/FitTest__it_can_fit_and_add_a_background_with_data_set_dataset_gd__1.png differ diff --git a/tests/__snapshots__/FitTest__it_can_fit_and_add_a_background_with_data_set_dataset_imagick__1.png b/tests/__snapshots__/FitTest__it_can_fit_and_add_a_background_with_data_set_dataset_imagick__1.png index 9a9e5fec..53d5c163 100644 Binary files a/tests/__snapshots__/FitTest__it_can_fit_and_add_a_background_with_data_set_dataset_imagick__1.png and b/tests/__snapshots__/FitTest__it_can_fit_and_add_a_background_with_data_set_dataset_imagick__1.png differ