From b8cc2431fcb05789ac2fabbdafcd29f1944e3c5d Mon Sep 17 00:00:00 2001 From: Oliver Vogel Date: Sun, 27 Jul 2014 12:44:21 +0200 Subject: [PATCH] added polygon drawing --- .../Image/Commands/PolygonCommand.php | 48 +++++++++++ .../Image/Gd/Shapes/PolygonShape.php | 48 +++++++++++ .../Image/Imagick/Shapes/PolygonShape.php | 80 +++++++++++++++++++ tests/GdSystemTest.php | 8 ++ tests/ImagickSystemTest.php | 8 ++ tests/PolygonCommandTest.php | 44 ++++++++++ tests/PolygonShapeTest.php | 56 +++++++++++++ 7 files changed, 292 insertions(+) create mode 100644 src/Intervention/Image/Commands/PolygonCommand.php create mode 100644 src/Intervention/Image/Gd/Shapes/PolygonShape.php create mode 100644 src/Intervention/Image/Imagick/Shapes/PolygonShape.php create mode 100644 tests/PolygonCommandTest.php create mode 100644 tests/PolygonShapeTest.php diff --git a/src/Intervention/Image/Commands/PolygonCommand.php b/src/Intervention/Image/Commands/PolygonCommand.php new file mode 100644 index 00000000..1f92c384 --- /dev/null +++ b/src/Intervention/Image/Commands/PolygonCommand.php @@ -0,0 +1,48 @@ +argument(0)->type('array')->required()->value(); + $callback = $this->argument(1)->type('closure')->value(); + + $vertices_count = count($points); + + // check if number if coordinates is even + if ($vertices_count % 2 !== 0) { + throw new \Intervention\Image\Exception\InvalidArgumentException( + "The number of given polygon vertices must be even." + ); + } + + if ($vertices_count < 6) { + throw new \Intervention\Image\Exception\InvalidArgumentException( + "You must have at least 3 points in your array." + ); + } + + $polygon_classname = sprintf('\Intervention\Image\%s\Shapes\PolygonShape', + $image->getDriver()->getDriverName()); + + $polygon = new $polygon_classname($points); + + if ($callback instanceof Closure) { + $callback($polygon); + } + + $polygon->applyToImage($image); + + return true; + } +} diff --git a/src/Intervention/Image/Gd/Shapes/PolygonShape.php b/src/Intervention/Image/Gd/Shapes/PolygonShape.php new file mode 100644 index 00000000..b64fb5d4 --- /dev/null +++ b/src/Intervention/Image/Gd/Shapes/PolygonShape.php @@ -0,0 +1,48 @@ +points = $points; + } + + /** + * Draw polygon on given image + * + * @param Image $image + * @param integer $x + * @param integer $y + * @return boolean + */ + public function applyToImage(Image $image, $x = 0, $y = 0) + { + $background = new Color($this->background); + imagefilledpolygon($image->getCore(), $this->points, intval(count($this->points) / 2), $background->getInt()); + + if ($this->hasBorder()) { + $border_color = new Color($this->border_color); + imagesetthickness($image->getCore(), $this->border_width); + imagepolygon($image->getCore(), $this->points, intval(count($this->points) / 2), $border_color->getInt()); + } + + return true; + } +} diff --git a/src/Intervention/Image/Imagick/Shapes/PolygonShape.php b/src/Intervention/Image/Imagick/Shapes/PolygonShape.php new file mode 100644 index 00000000..dec4a339 --- /dev/null +++ b/src/Intervention/Image/Imagick/Shapes/PolygonShape.php @@ -0,0 +1,80 @@ +points = $this->formatPoints($points); + } + + /** + * Draw polygon on given image + * + * @param Image $image + * @param integer $x + * @param integer $y + * @return boolean + */ + public function applyToImage(Image $image, $x = 0, $y = 0) + { + $polygon = new \ImagickDraw; + + // set background + $bgcolor = new Color($this->background); + $polygon->setFillColor($bgcolor->getPixel()); + + // set border + if ($this->hasBorder()) { + $border_color = new Color($this->border_color); + $polygon->setStrokeWidth($this->border_width); + $polygon->setStrokeColor($border_color->getPixel()); + } + + $polygon->polygon($this->points); + + $image->getCore()->drawImage($polygon); + + return true; + } + + /** + * Format polygon points to Imagick format + * + * @param Array $points + * @return Array + */ + private function formatPoints($points) + { + $ipoints = array(); + $count = 1; + + foreach ($points as $key => $value) { + if ($count%2 === 0) { + $y = $value; + $ipoints[] = array('x' => $x, 'y' => $y); + } else { + $x = $value; + } + $count++; + } + + return $ipoints; + } +} diff --git a/tests/GdSystemTest.php b/tests/GdSystemTest.php index d66ede0f..28790b1c 100644 --- a/tests/GdSystemTest.php +++ b/tests/GdSystemTest.php @@ -1027,6 +1027,14 @@ class GdSystemTest extends PHPUnit_Framework_TestCase $this->assertEquals('c214f58de03d171f7f278a7b957bab50', $img->checksum()); } + public function testPolygonImage() + { + $img = $this->manager()->canvas(16, 16, 'ffffff'); + $points = array(3, 3, 11, 11, 7, 13); + $img->polygon($points, function ($draw) { $draw->background('#ff0000'); $draw->border(1, '#0000ff'); }); + $this->assertEquals('e534ff90c8026f9317b99071fda01ed4', $img->checksum()); + } + public function testResetImage() { $img = $this->manager()->make('tests/images/tile.png'); diff --git a/tests/ImagickSystemTest.php b/tests/ImagickSystemTest.php index ffaff417..ab7cda00 100644 --- a/tests/ImagickSystemTest.php +++ b/tests/ImagickSystemTest.php @@ -1000,6 +1000,14 @@ class ImagickSystemTest extends PHPUnit_Framework_TestCase $this->assertEquals('a433c7c1a842ef83e1cb45875371358c', $img->checksum()); } + public function testPolygonImage() + { + $img = $this->manager()->canvas(16, 16, 'ffffff'); + $points = array(3, 3, 11, 11, 7, 13); + $img->polygon($points, function ($draw) { $draw->background('#ff0000'); $draw->border(1, '#0000ff'); }); + $this->assertEquals('e301afe179da858d441ad8fc0eb5490a', $img->checksum()); + } + public function testResetImage() { $img = $this->manager()->make('tests/images/tile.png'); diff --git a/tests/PolygonCommandTest.php b/tests/PolygonCommandTest.php new file mode 100644 index 00000000..c3eaf716 --- /dev/null +++ b/tests/PolygonCommandTest.php @@ -0,0 +1,44 @@ +shouldReceive('getDriverName')->once()->andReturn('Gd'); + $image = Mockery::mock('\Intervention\Image\Image'); + $image->shouldReceive('getDriver')->once()->andReturn($driver); + $image->shouldReceive('getCore')->once()->andReturn($resource); + $command = new PolygonCommand(array($points)); + $result = $command->execute($image); + $this->assertTrue($result); + $this->assertFalse($command->hasOutput()); + } + + public function testImagick() + { + $points = array(1, 2, 3, 4, 5, 6); + $imagick = Mockery::mock('\Imagick'); + $imagick->shouldReceive('drawimage'); + $driver = Mockery::mock('\Intervention\Image\Imagick\Driver'); + $driver->shouldReceive('getDriverName')->once()->andReturn('Imagick'); + $image = Mockery::mock('\Intervention\Image\Image'); + $image->shouldReceive('getDriver')->once()->andReturn($driver); + $image->shouldReceive('getCore')->once()->andReturn($imagick); + + $command = new PolygonCommand(array($points)); + $result = $command->execute($image); + $this->assertTrue($result); + $this->assertFalse($command->hasOutput()); + } + +} diff --git a/tests/PolygonShapeTest.php b/tests/PolygonShapeTest.php new file mode 100644 index 00000000..4f87b2b3 --- /dev/null +++ b/tests/PolygonShapeTest.php @@ -0,0 +1,56 @@ +assertInstanceOf('Intervention\Image\Gd\Shapes\PolygonShape', $polygon); + $this->assertEquals(array(1, 2, 3, 4, 5, 6), $polygon->points); + + } + + public function testGdApplyToImage() + { + $core = imagecreatetruecolor(300, 200); + $image = Mockery::mock('\Intervention\Image\Image'); + $image->shouldReceive('getCore')->once()->andReturn($core); + $polygon = new PolygonGd(array(1, 2, 3, 4, 5, 6)); + $result = $polygon->applyToImage($image); + $this->assertInstanceOf('Intervention\Image\Gd\Shapes\PolygonShape', $polygon); + $this->assertTrue($result); + } + + public function testImagickConstructor() + { + $polygon = new PolygonImagick(array(1, 2, 3, 4, 5, 6)); + $this->assertInstanceOf('Intervention\Image\Imagick\Shapes\PolygonShape', $polygon); + $this->assertEquals(array( + array('x' => 1, 'y' => 2), + array('x' => 3, 'y' => 4), + array('x' => 5, 'y' => 6)), + $polygon->points); + + } + + public function testImagickApplyToImage() + { + $core = Mockery::mock('\Imagick'); + $core->shouldReceive('drawimage')->once(); + $image = Mockery::mock('\Intervention\Image\Image'); + $image->shouldReceive('getCore')->once()->andReturn($core); + $polygon = new PolygonImagick(array(1, 2, 3, 4, 5, 6)); + $result = $polygon->applyToImage($image); + $this->assertInstanceOf('Intervention\Image\Imagick\Shapes\PolygonShape', $polygon); + $this->assertTrue($result); + } + +}