From 9564d595b773dece175c2aaa3d48765ce01d9b56 Mon Sep 17 00:00:00 2001 From: Oliver Vogel Date: Mon, 5 Aug 2024 17:13:31 +0200 Subject: [PATCH 1/3] Implement new method ColorInterface::isClear() --- src/Colors/Cmyk/Color.php | 10 ++++++++++ src/Colors/Hsl/Color.php | 10 ++++++++++ src/Colors/Hsv/Color.php | 10 ++++++++++ src/Colors/Rgb/Color.php | 10 ++++++++++ src/Interfaces/ColorInterface.php | 7 +++++++ tests/Unit/Colors/Cmyk/ColorTest.php | 6 ++++++ tests/Unit/Colors/Hsl/ColorTest.php | 6 ++++++ tests/Unit/Colors/Hsv/ColorTest.php | 6 ++++++ tests/Unit/Colors/Rgb/ColorTest.php | 15 +++++++++++++++ 9 files changed, 80 insertions(+) diff --git a/src/Colors/Cmyk/Color.php b/src/Colors/Cmyk/Color.php index 5aad25a4..d3229e6c 100644 --- a/src/Colors/Cmyk/Color.php +++ b/src/Colors/Cmyk/Color.php @@ -152,4 +152,14 @@ public function isTransparent(): bool { return false; } + + /** + * {@inheritdoc} + * + * @see ColorInterface::isClear() + */ + public function isClear(): bool + { + return false; + } } diff --git a/src/Colors/Hsl/Color.php b/src/Colors/Hsl/Color.php index e682f9a2..20ca0e5d 100644 --- a/src/Colors/Hsl/Color.php +++ b/src/Colors/Hsl/Color.php @@ -120,4 +120,14 @@ public function isTransparent(): bool { return false; } + + /** + * {@inheritdoc} + * + * @see ColorInterface::isClear() + */ + public function isClear(): bool + { + return false; + } } diff --git a/src/Colors/Hsv/Color.php b/src/Colors/Hsv/Color.php index 9c7f285c..8a4f18b2 100644 --- a/src/Colors/Hsv/Color.php +++ b/src/Colors/Hsv/Color.php @@ -120,4 +120,14 @@ public function isTransparent(): bool { return false; } + + /** + * {@inheritdoc} + * + * @see ColorInterface::isClear() + */ + public function isClear(): bool + { + return false; + } } diff --git a/src/Colors/Rgb/Color.php b/src/Colors/Rgb/Color.php index f97a9241..4926a73c 100644 --- a/src/Colors/Rgb/Color.php +++ b/src/Colors/Rgb/Color.php @@ -178,4 +178,14 @@ public function isTransparent(): bool { return $this->alpha()->value() < $this->alpha()->max(); } + + /** + * {@inheritdoc} + * + * @see ColorInterface::isClear() + */ + public function isClear(): bool + { + return $this->alpha()->value() == 0; + } } diff --git a/src/Interfaces/ColorInterface.php b/src/Interfaces/ColorInterface.php index 33c44bc7..b72f1fcc 100644 --- a/src/Interfaces/ColorInterface.php +++ b/src/Interfaces/ColorInterface.php @@ -97,4 +97,11 @@ public function isGreyscale(): bool; * @return bool */ public function isTransparent(): bool; + + /** + * Determine whether the current color is completely transparent + * + * @return bool + */ + public function isClear(): bool; } diff --git a/tests/Unit/Colors/Cmyk/ColorTest.php b/tests/Unit/Colors/Cmyk/ColorTest.php index 3ae51d7d..7fae9ea4 100644 --- a/tests/Unit/Colors/Cmyk/ColorTest.php +++ b/tests/Unit/Colors/Cmyk/ColorTest.php @@ -111,4 +111,10 @@ public function testIsTransparent(): void $color = new Color(100, 50, 50, 0); $this->assertFalse($color->isTransparent()); } + + public function testIsClear(): void + { + $color = new Color(0, 0, 0, 0); + $this->assertFalse($color->isClear()); + } } diff --git a/tests/Unit/Colors/Hsl/ColorTest.php b/tests/Unit/Colors/Hsl/ColorTest.php index 9f503bf5..749d21b0 100644 --- a/tests/Unit/Colors/Hsl/ColorTest.php +++ b/tests/Unit/Colors/Hsl/ColorTest.php @@ -108,4 +108,10 @@ public function testIsTransparent(): void $color = new Color(0, 1, 0); $this->assertFalse($color->isTransparent()); } + + public function testIsClear(): void + { + $color = new Color(0, 1, 0); + $this->assertFalse($color->isClear()); + } } diff --git a/tests/Unit/Colors/Hsv/ColorTest.php b/tests/Unit/Colors/Hsv/ColorTest.php index 930c54ff..f4a270b2 100644 --- a/tests/Unit/Colors/Hsv/ColorTest.php +++ b/tests/Unit/Colors/Hsv/ColorTest.php @@ -108,4 +108,10 @@ public function testIsTransparent(): void $color = new Color(1, 0, 0); $this->assertFalse($color->isTransparent()); } + + public function testIsClear(): void + { + $color = new Color(0, 1, 0); + $this->assertFalse($color->isClear()); + } } diff --git a/tests/Unit/Colors/Rgb/ColorTest.php b/tests/Unit/Colors/Rgb/ColorTest.php index 6fb2051e..16bfd1ed 100644 --- a/tests/Unit/Colors/Rgb/ColorTest.php +++ b/tests/Unit/Colors/Rgb/ColorTest.php @@ -163,4 +163,19 @@ public function testIsTransparent(): void $color = new Color(255, 255, 255, 0); $this->assertTrue($color->isTransparent()); } + + public function testIsClear(): void + { + $color = new Color(255, 255, 255); + $this->assertFalse($color->isClear()); + + $color = new Color(255, 255, 255, 255); + $this->assertFalse($color->isClear()); + + $color = new Color(255, 255, 255, 85); + $this->assertFalse($color->isClear()); + + $color = new Color(255, 255, 255, 0); + $this->assertTrue($color->isClear()); + } } From cee93bd6a8d17fb4c888b0b617dab90684e9787c Mon Sep 17 00:00:00 2001 From: Oliver Vogel Date: Mon, 5 Aug 2024 17:22:33 +0200 Subject: [PATCH 2/3] Fix bug in Cloner::cloneEmpty() If an image was cloned with cloneEmpty() and a fully transparent color for exampe "rgba(255, 255, 255, 0)" the turned out as white background. This patch sets the background color as fully transparent if it has an alpha channel value of 0 i.e. 100% transparent (clear). --- src/Drivers/Gd/Cloner.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Drivers/Gd/Cloner.php b/src/Drivers/Gd/Cloner.php index 8edc2023..d29d9add 100644 --- a/src/Drivers/Gd/Cloner.php +++ b/src/Drivers/Gd/Cloner.php @@ -67,6 +67,10 @@ public static function cloneEmpty( imagealphablending($clone, true); imagesavealpha($clone, true); + if ($background->isClear()) { + imagecolortransparent($clone, $processor->colorToNative($background)); + } + return $clone; } From 6a4607dd9a4db77b838bf4426d95e9cd532310e2 Mon Sep 17 00:00:00 2001 From: Oliver Vogel Date: Sun, 11 Aug 2024 11:59:10 +0200 Subject: [PATCH 3/3] Adjust logic of cloner transparency application --- src/Drivers/Gd/Cloner.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Drivers/Gd/Cloner.php b/src/Drivers/Gd/Cloner.php index d29d9add..8723006a 100644 --- a/src/Drivers/Gd/Cloner.php +++ b/src/Drivers/Gd/Cloner.php @@ -5,6 +5,7 @@ namespace Intervention\Image\Drivers\Gd; use GdImage; +use Intervention\Image\Colors\Rgb\Channels\Alpha; use Intervention\Image\Colors\Rgb\Color; use Intervention\Image\Exceptions\ColorException; use Intervention\Image\Geometry\Rectangle; @@ -67,7 +68,9 @@ public static function cloneEmpty( imagealphablending($clone, true); imagesavealpha($clone, true); - if ($background->isClear()) { + // set background image as transparent if alpha channel value if color is below .5 + // comes into effect when the end format only supports binary transparency (like GIF) + if ($background->channel(Alpha::class)->value() < 128) { imagecolortransparent($clone, $processor->colorToNative($background)); }