diff --git a/readme.md b/readme.md index 8cd173c..0377b12 100644 --- a/readme.md +++ b/readme.md @@ -82,7 +82,7 @@ the features that have already been implemented. | Image::scaleDown() | ✅ | | Image::cover() | ✅ | | Image::coverDown() | ✅ | -| Image::pad() | ❌ | +| Image::pad() | ✅ | | Image::contain() | ✅ | | Image::crop() | ✅ | | Image::resizeCanvas() | ✅ | diff --git a/src/Modifiers/PadModifier.php b/src/Modifiers/PadModifier.php new file mode 100644 index 0000000..57cebc5 --- /dev/null +++ b/src/Modifiers/PadModifier.php @@ -0,0 +1,89 @@ +getResizeSize($image); + $bgColor = $this->driver()->handleInput($this->background); + + if (!$image->isAnimated()) { + $contained = $this->pad($image->core()->first(), $resize, $bgColor)->native(); + } else { + $frames = []; + foreach ($image as $frame) { + $frames[] = $this->pad($frame, $resize, $bgColor); + } + + $contained = Core::replaceFrames($image->core()->native(), $frames); + } + + $image->core()->setNative($contained); + + return $image; + } + + /** + * Apply padded image resizing + * + * @param FrameInterface $frame + * @param SizeInterface $resize + * @param ColorInterface $bgColor + * @return FrameInterface + * @throws ColorException + */ + private function pad(FrameInterface $frame, SizeInterface $resize, ColorInterface $bgColor): FrameInterface + { + $cropWidth = min($frame->native()->width, $resize->width()); + $cropHeight = min($frame->native()->height, $resize->height()); + + $resized = $frame->native()->thumbnail_image($cropWidth, [ + 'height' => $cropHeight, + 'no_rotate' => true, + ]); + + if (!$resized->hasAlpha()) { + $resized = $resized->bandjoin_const(255); + } + + $frame->setNative( + $resized->gravity( + $this->positionToGravity($this->position), + $resize->width(), + $resize->height(), + [ + 'extend' => Extend::BACKGROUND, + 'background' => [ + $bgColor->channel(Red::class)->value(), + $bgColor->channel(Green::class)->value(), + $bgColor->channel(Blue::class)->value(), + $bgColor->channel(Alpha::class)->value(), + ], + ] + ) + ); + + return $frame; + } +} diff --git a/tests/Unit/Modifiers/PadModifierTest.php b/tests/Unit/Modifiers/PadModifierTest.php new file mode 100644 index 0000000..0af3ed0 --- /dev/null +++ b/tests/Unit/Modifiers/PadModifierTest.php @@ -0,0 +1,39 @@ +readTestImage('blue.gif'); + $this->assertEquals(16, $image->width()); + $this->assertEquals(16, $image->height()); + $image->modify(new PadModifier(30, 20, 'f00')); + $this->assertEquals(30, $image->width()); + $this->assertEquals(20, $image->height()); + $this->assertColor(255, 0, 0, 255, $image->pickColor(0, 0)); + $this->assertColor(255, 0, 0, 255, $image->pickColor(0, 19)); + $this->assertColor(255, 0, 0, 255, $image->pickColor(29, 0)); + $this->assertColor(255, 0, 0, 255, $image->pickColor(29, 19)); + $this->assertColor(255, 0, 0, 255, $image->pickColor(6, 2)); + $this->assertColor(255, 0, 0, 255, $image->pickColor(7, 1)); + $this->assertColor(255, 0, 0, 255, $image->pickColor(6, 17)); + $this->assertColor(255, 0, 0, 255, $image->pickColor(7, 18)); + $this->assertColor(255, 0, 0, 255, $image->pickColor(23, 1)); + $this->assertColor(255, 0, 0, 255, $image->pickColor(23, 2)); + $this->assertColor(255, 0, 0, 255, $image->pickColor(23, 17)); + $this->assertColor(255, 0, 0, 255, $image->pickColor(23, 18)); + $this->assertColor(100, 100, 255, 255, $image->pickColor(7, 2)); + $this->assertColor(100, 100, 255, 255, $image->pickColor(22, 2)); + $this->assertColor(100, 100, 255, 255, $image->pickColor(7, 17)); + $this->assertColor(100, 100, 255, 255, $image->pickColor(22, 17)); + } +}