Skip to content

Commit

Permalink
Fix ignored opacity in Imagick's PlaceModifer for certain files. (#1346)
Browse files Browse the repository at this point in the history
* Add tests to reproduce bug in PlaceModifier
* Fix bug in PlaceModifier
* Add tolerance parameter to BaseTestCase::assertColor()
  • Loading branch information
olivervogel committed May 5, 2024
1 parent 1cc333c commit ab403d9
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/Drivers/Imagick/Modifiers/PlaceModifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public function apply(ImageInterface $image): ImageInterface

// set opacity of watermark
if ($this->opacity < 100) {
$watermark->core()->native()->setImageAlphaChannel(Imagick::ALPHACHANNEL_OPAQUE);
$watermark->core()->native()->evaluateImage(
Imagick::EVALUATE_DIVIDE,
$this->opacity > 0 ? 100 / $this->opacity : 1000,
Expand Down
55 changes: 53 additions & 2 deletions tests/BaseTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,14 @@
namespace Intervention\Image\Tests;

use Intervention\Image\Colors\Rgb\Channels\Alpha;
use Intervention\Image\Colors\Rgb\Channels\Blue;
use Intervention\Image\Colors\Rgb\Channels\Green;
use Intervention\Image\Colors\Rgb\Channels\Red;
use Intervention\Image\Colors\Rgb\Color as RgbColor;
use Intervention\Image\Colors\Rgb\Colorspace;
use Intervention\Image\Interfaces\ColorInterface;
use Mockery\Adapter\Phpunit\MockeryTestCase;
use PHPUnit\Framework\ExpectationFailedException;

abstract class BaseTestCase extends MockeryTestCase
{
Expand All @@ -30,9 +35,55 @@ public function getTestResourcePointer($filename = 'test.jpg')
return $pointer;
}

protected function assertColor($r, $g, $b, $a, ColorInterface $color)
/**
* Assert that given color equals the given color channel values in the given optional tolerance
*
* @param int $r
* @param int $g
* @param int $b
* @param int $a
* @param ColorInterface $color
* @param int $tolerance
* @throws ExpectationFailedException
* @return void
*/
protected function assertColor(int $r, int $g, int $b, int $a, ColorInterface $color, int $tolerance = 0)
{
$this->assertEquals([$r, $g, $b, $a], $color->toArray());
$this->assertContains(
$color->channel(Red::class)->value(),
range(max($r - $tolerance, 0), min($r + $tolerance, 255)),
'Failed asserting that color ' .
$color->convertTo(Colorspace::class)->toString() .
' equals '
. $color->convertTo(Colorspace::class)->toString()
);

$this->assertContains(
$color->channel(Green::class)->value(),
range(max($g - $tolerance, 0), min($g + $tolerance, 255)),
'Failed asserting that color ' .
$color->convertTo(Colorspace::class)->toString() .
' equals '
. $color->convertTo(Colorspace::class)->toString()
);

$this->assertContains(
$color->channel(Blue::class)->value(),
range(max($b - $tolerance, 0), min($b + $tolerance, 255)),
'Failed asserting that color ' .
$color->convertTo(Colorspace::class)->toString() .
' equals '
. $color->convertTo(Colorspace::class)->toString()
);

$this->assertContains(
$color->channel(Alpha::class)->value(),
range(max($a - $tolerance, 0), min($a + $tolerance, 255)),
'Failed asserting that color ' .
$color->convertTo(Colorspace::class)->toString() .
' equals '
. $color->convertTo(Colorspace::class)->toString()
);
}

protected function assertTransparency(ColorInterface $color)
Expand Down
10 changes: 9 additions & 1 deletion tests/Unit/Drivers/Gd/Modifiers/PlaceModifierTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,19 @@ public function testColorChange(): void
$this->assertEquals('32250d', $image->pickColor(300, 25)->toHex());
}

public function testColorChangeOpacity(): void
public function testColorChangeOpacityPng(): void
{
$image = $this->readTestImage('test.jpg');
$this->assertEquals('febc44', $image->pickColor(300, 25)->toHex());
$image->modify(new PlaceModifier($this->getTestResourcePath('circle.png'), 'top-right', 0, 0, 50));
$this->assertEquals('987028', $image->pickColor(300, 25)->toHex());
}

public function testColorChangeOpacityJpeg(): void
{
$image = $this->createTestImage(16, 16)->fill('0000ff');
$this->assertEquals('0000ff', $image->pickColor(10, 10)->toHex());
$image->modify(new PlaceModifier($this->getTestResourcePath('exif.jpg'), opacity: 50));
$this->assertColor(127, 83, 127, 255, $image->pickColor(10, 10), tolerance: 1);
}
}
12 changes: 10 additions & 2 deletions tests/Unit/Drivers/Imagick/Modifiers/PlaceModifierTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,19 @@ public function testColorChange(): void
$this->assertEquals('33260e', $image->pickColor(300, 25)->toHex());
}

public function testColorChangeOpacity(): void
public function testColorChangeOpacityPng(): void
{
$image = $this->readTestImage('test.jpg');
$this->assertEquals('febc44', $image->pickColor(300, 25)->toHex());
$image->modify(new PlaceModifier($this->getTestResourcePath('circle.png'), 'top-right', 0, 0, 50));
$this->assertEquals('987129', $image->pickColor(300, 25)->toHex());
$this->assertEquals('7f5e22', $image->pickColor(300, 25)->toHex());
}

public function testColorChangeOpacityJpeg(): void
{
$image = $this->createTestImage(16, 16)->fill('0000ff');
$this->assertEquals('0000ff', $image->pickColor(10, 10)->toHex());
$image->modify(new PlaceModifier($this->getTestResourcePath('exif.jpg'), opacity: 50));
$this->assertColor(127, 83, 127, 255, $image->pickColor(10, 10), tolerance: 1);
}
}

0 comments on commit ab403d9

Please sign in to comment.