diff --git a/src/Drivers/Abstract/AbstractImage.php b/src/Drivers/Abstract/AbstractImage.php index 2f643625..f9870ace 100644 --- a/src/Drivers/Abstract/AbstractImage.php +++ b/src/Drivers/Abstract/AbstractImage.php @@ -127,125 +127,103 @@ abstract class AbstractImage public function resize(...$arguments): ImageInterface { - $crop = $this->getSize(); - $resize = Resizer::make() - ->setTargetSizeByArray($arguments) - ->resize($crop); + $resized = Resizer::make()->setTargetSizeByArray($arguments) + ->resize($this->getSize()); return $this->modify( - $this->resolveDriverClass('Modifiers\CropResizeModifier', $crop, $resize) + $this->resolveDriverClass('Modifiers\ResizeModifier', $resized) ); } public function resizeDown(...$arguments): ImageInterface { - $crop = $this->getSize(); - $resize = Resizer::make() - ->setTargetSizeByArray($arguments) - ->resizeDown($crop); + $resized = Resizer::make()->setTargetSizeByArray($arguments) + ->resizeDown($this->getSize()); return $this->modify( - $this->resolveDriverClass('Modifiers\CropResizeModifier', $crop, $resize) + $this->resolveDriverClass('Modifiers\ResizeModifier', $resized) ); } public function scale(...$arguments): ImageInterface { - $crop = $this->getSize(); - $resize = Resizer::make() - ->setTargetSizeByArray($arguments) - ->scale($crop); + $resized = Resizer::make()->setTargetSizeByArray($arguments) + ->scale($this->getSize()); return $this->modify( - $this->resolveDriverClass('Modifiers\CropResizeModifier', $crop, $resize) + $this->resolveDriverClass('Modifiers\ResizeModifier', $resized) ); } public function scaleDown(...$arguments): ImageInterface { - $crop = $this->getSize(); - $resize = Resizer::make() - ->setTargetSizeByArray($arguments) - ->scaleDown($crop); + $resized = Resizer::make()->setTargetSizeByArray($arguments) + ->scaleDown($this->getSize()); return $this->modify( - $this->resolveDriverClass('Modifiers\CropResizeModifier', $crop, $resize) + $this->resolveDriverClass('Modifiers\ResizeModifier', $resized) ); } public function fit(int $width, int $height, string $position = 'center'): ImageInterface { + // original $imagesize = $this->getSize(); // crop $crop = new Size($width, $height); - $crop = $crop->contain($imagesize)->alignPivotTo( - $imagesize->alignPivot($position), - $position - ); + $crop = $crop->contain($imagesize)->alignPivotTo($imagesize, $position); // resize $resize = $crop->scale($width, $height); return $this->modify( - $this->resolveDriverClass('Modifiers\CropResizeModifier', $crop, $resize, $position) + $this->resolveDriverClass('Modifiers\FitModifier', $crop, $resize) ); } public function fitDown(int $width, int $height, string $position = 'center'): ImageInterface { + // original $imagesize = $this->getSize(); // crop $crop = new Size($width, $height); - $crop = $crop->contain($imagesize)->alignPivotTo( - $imagesize->alignPivot($position), - $position - ); + $crop = $crop->contain($imagesize)->alignPivotTo($imagesize, $position); // resize $resize = $crop->scaleDown($width, $height); return $this->modify( - $this->resolveDriverClass('Modifiers\CropResizeModifier', $crop, $resize, $position) + $this->resolveDriverClass('Modifiers\FitModifier', $crop, $resize) ); } - public function pad(int $width, int $height, string $position = 'center'): ImageInterface + public function pad(int $width, int $height, string $position = 'center', $backgroundColor = 'fff'): ImageInterface { + // original $imagesize = $this->getSize(); - // crop - $crop = new Size($width, $height); - $crop = $crop->cover($imagesize)->alignPivotTo( - $imagesize->alignPivot($position), - $position - ); - - // resize - $resize = $crop->scale($width, $height); + $resize = new Size($width, $height); + $crop = $imagesize->contain($resize)->alignPivotTo($resize, $position); return $this->modify( - $this->resolveDriverClass('Modifiers\CropResizeModifier', $crop, $resize, $position) + $this->resolveDriverClass('Modifiers\FitModifier', $crop, $resize, $backgroundColor) ); } - public function padDown(int $width, int $height, string $position = 'center'): ImageInterface + public function padDown(int $width, int $height, string $position = 'center', $backgroundColor = 'fff'): ImageInterface { + // original $imagesize = $this->getSize(); - // crop - $crop = new Size($width, $height); - $crop = $crop->cover($imagesize)->alignPivotTo( - $imagesize->alignPivot($position), - $position - ); + $resize = new Size($width, $height); + $resize = $resize->resizeDown($imagesize); + $crop = $imagesize->contain($resize)->alignPivotTo($resize, $position); - // resize - $resize = $crop->scaleDown($width, $height); return $this->modify( - $this->resolveDriverClass('Modifiers\CropResizeModifier', $crop, $resize, $position) + $this->resolveDriverClass('Modifiers\FitModifier', $crop, $resize, $backgroundColor) ); } diff --git a/src/Drivers/Gd/Modifiers/CropResizeModifier.php b/src/Drivers/Gd/Modifiers/FitModifier.php similarity index 58% rename from src/Drivers/Gd/Modifiers/CropResizeModifier.php rename to src/Drivers/Gd/Modifiers/FitModifier.php index efccf46c..ac6bef20 100644 --- a/src/Drivers/Gd/Modifiers/CropResizeModifier.php +++ b/src/Drivers/Gd/Modifiers/FitModifier.php @@ -6,43 +6,50 @@ use Intervention\Image\Interfaces\FrameInterface; use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\ModifierInterface; use Intervention\Image\Interfaces\SizeInterface; +use Intervention\Image\Traits\CanHandleInput; use Intervention\Image\Traits\CanResizeGeometrically; -class CropResizeModifier implements ModifierInterface +class FitModifier implements ModifierInterface { + use CanHandleInput; + protected $crop; protected $resize; - protected $position; + protected $backgroundColor; - public function __construct(SizeInterface $crop, SizeInterface $resize, string $position = 'top-left') + public function __construct(SizeInterface $crop, SizeInterface $resize, $backgroundColor = null) { $this->crop = $crop; $this->resize = $resize; - $this->position = $position; + $this->backgroundColor = $backgroundColor; } public function apply(ImageInterface $image): ImageInterface { foreach ($image as $frame) { - $this->modify($frame, $this->crop, $this->resize); + $this->modify($frame); } return $image; } - protected function modify(FrameInterface $frame, SizeInterface $crop, SizeInterface $resize): void + protected function modify(FrameInterface $frame): void { // create new image $modified = imagecreatetruecolor( - $resize->getWidth(), - $resize->getHeight() + $this->resize->getWidth(), + $this->resize->getHeight() ); + $color = $this->handleInput($this->backgroundColor); + + imagefill($modified, 0, 0, $color->toInt()); + // get current image - $gd = $frame->getCore(); + $current = $frame->getCore(); // preserve transparency - $transIndex = imagecolortransparent($gd); + $transIndex = imagecolortransparent($current); if ($transIndex != -1) { $rgba = imagecolorsforindex($modified, $transIndex); @@ -55,20 +62,20 @@ class CropResizeModifier implements ModifierInterface } // copy content from resource - $result = imagecopyresampled( + imagecopyresampled( $modified, - $gd, - $resize->getPivot()->getX(), - $resize->getPivot()->getY(), - $crop->getPivot()->getX(), - $crop->getPivot()->getY(), - $resize->getWidth(), - $resize->getHeight(), - $crop->getWidth(), - $crop->getHeight() + $current, + $this->crop->getPivot()->getX(), + $this->crop->getPivot()->getY(), + 0, + 0, + $this->crop->getWidth(), + $this->crop->getHeight(), + $frame->getSize()->getWidth(), + $frame->getSize()->getHeight() ); - imagedestroy($gd); + imagedestroy($current); // set new content as recource $frame->setCore($modified); diff --git a/src/Drivers/Gd/Modifiers/ResizeModifier.php b/src/Drivers/Gd/Modifiers/ResizeModifier.php new file mode 100644 index 00000000..7ad14d3e --- /dev/null +++ b/src/Drivers/Gd/Modifiers/ResizeModifier.php @@ -0,0 +1,72 @@ +resize = $resize; + } + + public function apply(ImageInterface $image): ImageInterface + { + foreach ($image as $frame) { + $this->modify($frame); + } + + return $image; + } + + protected function modify(FrameInterface $frame): void + { + // create new image + $modified = imagecreatetruecolor( + $this->resize->getWidth(), + $this->resize->getHeight() + ); + + // get current image + $current = $frame->getCore(); + + // preserve transparency + $transIndex = imagecolortransparent($current); + + if ($transIndex != -1) { + $rgba = imagecolorsforindex($modified, $transIndex); + $transColor = imagecolorallocatealpha($modified, $rgba['red'], $rgba['green'], $rgba['blue'], 127); + imagefill($modified, 0, 0, $transColor); + imagecolortransparent($modified, $transColor); + } else { + imagealphablending($modified, false); + imagesavealpha($modified, true); + } + + // copy content from resource + imagecopyresampled( + $modified, + $current, + $this->resize->getPivot()->getX(), + $this->resize->getPivot()->getY(), + 0, + 0, + $this->resize->getWidth(), + $this->resize->getHeight(), + $frame->getSize()->getWidth(), + $frame->getSize()->getHeight() + ); + + imagedestroy($current); + + // set new content as recource + $frame->setCore($modified); + } +}