diff --git a/src/Drivers/Imagick/Modifiers/PadModifier.php b/src/Drivers/Imagick/Modifiers/PadModifier.php index b858481e..c0b3e2f0 100644 --- a/src/Drivers/Imagick/Modifiers/PadModifier.php +++ b/src/Drivers/Imagick/Modifiers/PadModifier.php @@ -2,16 +2,11 @@ namespace Intervention\Image\Drivers\Imagick\Modifiers; -use Imagick; use ImagickDraw; use ImagickPixel; -use Intervention\Image\Colors\Rgb\Color; use Intervention\Image\Drivers\DriverModifier; -use Intervention\Image\Drivers\Imagick\Core; -use Intervention\Image\Image; use Intervention\Image\Interfaces\ImageInterface; use Intervention\Image\Interfaces\SizeInterface; -use Intervention\Image\Modifiers\FillModifier; /** * @method SizeInterface getCropSize(ImageInterface $image) @@ -25,63 +20,71 @@ class PadModifier extends DriverModifier { public function apply(ImageInterface $image): ImageInterface { + $crop = $this->getCropSize($image); $resize = $this->getResizeSize($image); - $background = $this->driver()->handleInput($this->background); + $transparent = new ImagickPixel('transparent'); + $background = $this->driver()->colorProcessor($image->colorspace())->colorToNative( + $this->driver()->handleInput($this->background) + ); - $imagick = new Imagick(); foreach ($image as $frame) { - // resize current core $frame->native()->scaleImage( $crop->width(), - $crop->height() + $crop->height(), ); - // create new canvas, to get newly emerged background color - $canvas = $this->buildBaseCanvas($crop, $resize, $background); + $frame->native()->setBackgroundColor($transparent); + $frame->native()->setImageBackgroundColor($transparent); - // place current core onto canvas - $canvas->compositeImage( - $frame->native(), - Imagick::COMPOSITE_DEFAULT, - $crop->pivot()->x(), - $crop->pivot()->y() + $frame->native()->extentImage( + $resize->width(), + $resize->height(), + $crop->pivot()->x() * -1, + $crop->pivot()->y() * -1 ); - $imagick->addImage($canvas); - } - - return new Image( - $image->driver(), - new Core($imagick), - $image->exif() - ); - } - - protected function buildBaseCanvas(SizeInterface $crop, SizeInterface $resize, Color $background): Imagick - { - // build base canvas in target size - $canvas = $this->driver()->createImage( - $resize->width(), - $resize->height() - )->modify( - new FillModifier($background) - )->core()->native(); + if ($resize->width() > $crop->width()) { + // fill new emerged background + $draw = new ImagickDraw(); + $draw->setFillColor($background); + $draw->rectangle( + 0, + 0, + $crop->pivot()->x() - 1, + $resize->height() + ); + $frame->native()->drawImage($draw); + $draw->rectangle( + $crop->pivot()->x() + $crop->width(), + 0, + $resize->width(), + $resize->height() + ); + $frame->native()->drawImage($draw); + } - // make area where image is placed transparent to keep - // transparency even if background-color is set - $draw = new ImagickDraw(); - $fill = $background->toHex('#') == '#ff0000' ? '#00ff00' : '#ff0000'; - $draw->setFillColor(new ImagickPixel($fill)); - $draw->rectangle( - $crop->pivot()->x(), - $crop->pivot()->y(), - $crop->pivot()->x() + $crop->width() - 1, - $crop->pivot()->y() + $crop->height() - 1 - ); - $canvas->drawImage($draw); - $canvas->transparentPaintImage($fill, 0, 0, false); + if ($resize->height() > $crop->height()) { + // fill new emerged background + $draw = new ImagickDraw(); + $draw->setFillColor($background); + $draw->rectangle( + 0, + 0, + $crop->width(), + $crop->pivot()->y() - 1 + ); + $frame->native()->drawImage($draw); + $draw->rectangle( + 0, + $crop->pivot()->y() + $crop->height(), + $resize->width(), + $resize->height() + ); + $frame->native()->drawImage($draw); + } + } - return $canvas; + return $image; } } diff --git a/src/Image.php b/src/Image.php index 9a1a7437..7945a9d6 100644 --- a/src/Image.php +++ b/src/Image.php @@ -584,7 +584,12 @@ public function place( */ public function fill(mixed $color, ?int $x = null, ?int $y = null): ImageInterface { - return $this->modify(new FillModifier($color, new Point($x, $y))); + return $this->modify( + new FillModifier( + $color, + (is_null($x) || is_null($y)) ? null : new Point($x, $y), + ), + ); } /** diff --git a/tests/Drivers/Imagick/Modifiers/PadModifierTest.php b/tests/Drivers/Imagick/Modifiers/PadModifierTest.php index 9e65d93b..5cc59a70 100644 --- a/tests/Drivers/Imagick/Modifiers/PadModifierTest.php +++ b/tests/Drivers/Imagick/Modifiers/PadModifierTest.php @@ -19,11 +19,16 @@ public function testModify(): void $image = $this->createTestImage('blocks.png'); $this->assertEquals(640, $image->width()); $this->assertEquals(480, $image->height()); - $image->modify(new PadModifier(200, 100, 'ff0')); + $result = $image->modify(new PadModifier(200, 100, 'ff0')); $this->assertEquals(200, $image->width()); $this->assertEquals(100, $image->height()); $this->assertColor(255, 255, 0, 255, $image->pickColor(0, 0)); - $this->assertColor(255, 0, 255, 0, $image->pickColor(140, 10)); + $this->assertColor(0, 0, 0, 0, $image->pickColor(140, 10)); $this->assertColor(255, 255, 0, 255, $image->pickColor(175, 10)); + $this->assertEquals(200, $result->width()); + $this->assertEquals(100, $result->height()); + $this->assertColor(255, 255, 0, 255, $result->pickColor(0, 0)); + $this->assertColor(0, 0, 0, 0, $result->pickColor(140, 10)); + $this->assertColor(255, 255, 0, 255, $result->pickColor(175, 10)); } }