mirror of
https://github.com/Intervention/image.git
synced 2025-08-30 09:10:21 +02:00
Fix bug in Imagick PadModifier
This commit is contained in:
@@ -2,16 +2,11 @@
|
|||||||
|
|
||||||
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
namespace Intervention\Image\Drivers\Imagick\Modifiers;
|
||||||
|
|
||||||
use Imagick;
|
|
||||||
use ImagickDraw;
|
use ImagickDraw;
|
||||||
use ImagickPixel;
|
use ImagickPixel;
|
||||||
use Intervention\Image\Colors\Rgb\Color;
|
|
||||||
use Intervention\Image\Drivers\DriverModifier;
|
use Intervention\Image\Drivers\DriverModifier;
|
||||||
use Intervention\Image\Drivers\Imagick\Core;
|
|
||||||
use Intervention\Image\Image;
|
|
||||||
use Intervention\Image\Interfaces\ImageInterface;
|
use Intervention\Image\Interfaces\ImageInterface;
|
||||||
use Intervention\Image\Interfaces\SizeInterface;
|
use Intervention\Image\Interfaces\SizeInterface;
|
||||||
use Intervention\Image\Modifiers\FillModifier;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @method SizeInterface getCropSize(ImageInterface $image)
|
* @method SizeInterface getCropSize(ImageInterface $image)
|
||||||
@@ -25,63 +20,71 @@ class PadModifier extends DriverModifier
|
|||||||
{
|
{
|
||||||
public function apply(ImageInterface $image): ImageInterface
|
public function apply(ImageInterface $image): ImageInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
$crop = $this->getCropSize($image);
|
$crop = $this->getCropSize($image);
|
||||||
$resize = $this->getResizeSize($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) {
|
foreach ($image as $frame) {
|
||||||
// resize current core
|
|
||||||
$frame->native()->scaleImage(
|
$frame->native()->scaleImage(
|
||||||
$crop->width(),
|
$crop->width(),
|
||||||
$crop->height()
|
$crop->height(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// create new canvas, to get newly emerged background color
|
$frame->native()->setBackgroundColor($transparent);
|
||||||
$canvas = $this->buildBaseCanvas($crop, $resize, $background);
|
$frame->native()->setImageBackgroundColor($transparent);
|
||||||
|
|
||||||
// place current core onto canvas
|
$frame->native()->extentImage(
|
||||||
$canvas->compositeImage(
|
$resize->width(),
|
||||||
$frame->native(),
|
$resize->height(),
|
||||||
Imagick::COMPOSITE_DEFAULT,
|
$crop->pivot()->x() * -1,
|
||||||
$crop->pivot()->x(),
|
$crop->pivot()->y() * -1
|
||||||
$crop->pivot()->y()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$imagick->addImage($canvas);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 new Image(
|
return $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();
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
return $canvas;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -584,7 +584,12 @@ final class Image implements ImageInterface, Countable
|
|||||||
*/
|
*/
|
||||||
public function fill(mixed $color, ?int $x = null, ?int $y = null): ImageInterface
|
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),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -19,11 +19,16 @@ class PadModifierTest extends TestCase
|
|||||||
$image = $this->createTestImage('blocks.png');
|
$image = $this->createTestImage('blocks.png');
|
||||||
$this->assertEquals(640, $image->width());
|
$this->assertEquals(640, $image->width());
|
||||||
$this->assertEquals(480, $image->height());
|
$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(200, $image->width());
|
||||||
$this->assertEquals(100, $image->height());
|
$this->assertEquals(100, $image->height());
|
||||||
$this->assertColor(255, 255, 0, 255, $image->pickColor(0, 0));
|
$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->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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user