1
0
mirror of https://github.com/Intervention/image.git synced 2025-09-02 18:32:56 +02:00

Implement Blending Color

This commit is contained in:
Oliver Vogel
2024-01-06 12:37:41 +01:00
parent ceacb64949
commit b198fe6a3a
21 changed files with 286 additions and 160 deletions

89
src/Drivers/Gd/Cloner.php Normal file
View File

@@ -0,0 +1,89 @@
<?php
namespace Intervention\Image\Drivers\Gd;
use GdImage;
use Intervention\Image\Colors\Rgb\Color;
use Intervention\Image\Geometry\Rectangle;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\SizeInterface;
class Cloner
{
/**
* Create a clone of the given GdImage
*
* @param GdImage $gd
* @return GdImage
*/
public static function clone(GdImage $gd): GdImage
{
// create empty canvas with same size
$clone = static::cloneEmpty($gd);
// transfer actual image to clone
imagecopy($clone, $gd, 0, 0, 0, 0, imagesx($gd), imagesy($gd));
return $clone;
}
/**
* Create an "empty" clone of the given GdImage
*
* This only retains the basic data without transferring the actual image.
* It is optionally possible to change the size of the result and set a
* background color.
*
* @param GdImage $gd
* @param null|SizeInterface $size
* @param ColorInterface $background
* @return GdImage
*/
public static function cloneEmpty(
GdImage $gd,
?SizeInterface $size = null,
ColorInterface $background = new Color(255, 255, 255, 0)
): GdImage {
// define size
$size = match (true) {
is_null($size) => new Rectangle(imagesx($gd), imagesy($gd)),
default => $size,
};
// create new gd image with same size or new given size
$clone = imagecreatetruecolor($size->width(), $size->height());
// copy resolution to clone
$resolution = imageresolution($gd);
if (is_array($resolution) && array_key_exists(0, $resolution) && array_key_exists(1, $resolution)) {
imageresolution($clone, $resolution[0], $resolution[1]);
}
// fill with background
$processor = new ColorProcessor();
imagefill($clone, 0, 0, $processor->colorToNative($background));
imagealphablending($clone, true);
imagesavealpha($clone, true);
return $clone;
}
/**
* Create a clone of an GdImage that is positioned on the specified background color.
* Possible transparent areas are mixed with this color.
*
* @param GdImage $gd
* @param ColorInterface $background
* @return GdImage
*/
public static function cloneBlended(GdImage $gd, ColorInterface $background): GdImage
{
// create empty canvas with same size
$clone = static::cloneEmpty($gd, background: $background);
// transfer actual image to clone
imagecopy($clone, $gd, 0, 0, 0, 0, imagesx($gd), imagesy($gd));
return $clone;
}
}

View File

@@ -9,6 +9,7 @@ use Intervention\Image\Interfaces\DecoderInterface;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Gif\Decoder as GifDecoder;
use Intervention\Gif\Splitter as GifSplitter;
use Intervention\Image\Drivers\Gd\Cloner;
use Intervention\Image\Drivers\Gd\Core;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\Exceptions\DecoderException;
@@ -38,17 +39,15 @@ class BinaryImageDecoder extends AbstractDecoder implements DecoderInterface
throw new DecoderException('Unable to decode input');
}
if (!imageistruecolor($gd)) {
imagepalettetotruecolor($gd);
}
imagesavealpha($gd, true);
// clone image to normalize transparency to #ffffff00
$normalized = Cloner::clone($gd);
imagedestroy($gd);
// build image instance
$image = new Image(
new Driver(),
new Core([
new Frame($gd)
new Frame($normalized)
]),
$this->extractExifData($input)
);

View File

@@ -3,6 +3,7 @@
namespace Intervention\Image\Drivers\Gd\Encoders;
use Intervention\Image\Drivers\DriverSpecializedEncoder;
use Intervention\Image\Drivers\Gd\Cloner;
use Intervention\Image\EncodedImage;
use Intervention\Image\Interfaces\ImageInterface;
@@ -13,9 +14,10 @@ class JpegEncoder extends DriverSpecializedEncoder
{
public function encode(ImageInterface $image): EncodedImage
{
$gd = $image->core()->native();
$data = $this->getBuffered(function () use ($gd) {
imagejpeg($gd, null, $this->quality);
$output = Cloner::cloneBlended($image->core()->native(), background: $image->blendingColor());
$data = $this->getBuffered(function () use ($output) {
imagejpeg($output, null, $this->quality);
});
return new EncodedImage($data, 'image/jpeg');

View File

@@ -107,35 +107,6 @@ class Frame implements FrameInterface
*/
public function __clone(): void
{
// create new clone image
$width = imagesx($this->native);
$height = imagesy($this->native);
$clone = match (imageistruecolor($this->native)) {
true => imagecreatetruecolor($width, $height),
default => imagecreate($width, $height),
};
// transfer resolution to clone
$resolution = imageresolution($this->native);
if (is_array($resolution) && array_key_exists(0, $resolution) && array_key_exists(1, $resolution)) {
imageresolution($clone, $resolution[0], $resolution[1]);
}
// transfer transparency to clone
$transIndex = imagecolortransparent($this->native);
if ($transIndex != -1) {
$rgba = imagecolorsforindex($clone, $transIndex);
$transColor = imagecolorallocatealpha($clone, $rgba['red'], $rgba['green'], $rgba['blue'], 127);
imagefill($clone, 0, 0, $transColor);
imagecolortransparent($clone, $transColor);
} else {
imagealphablending($clone, false);
imagesavealpha($clone, true);
}
// transfer actual image to clone
imagecopy($clone, $this->native, 0, 0, 0, 0, $width, $height);
$this->native = $clone;
$this->native = Cloner::clone($this->native);
}
}

View File

@@ -5,12 +5,12 @@ namespace Intervention\Image\Drivers\Gd\Modifiers;
use Intervention\Image\Colors\Rgb\Channels\Blue;
use Intervention\Image\Colors\Rgb\Channels\Green;
use Intervention\Image\Colors\Rgb\Channels\Red;
use Intervention\Image\Drivers\Gd\Cloner;
use Intervention\Image\Drivers\Gd\SpecializedModifier;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\FrameInterface;
use Intervention\Image\Interfaces\ImageInterface;
use Intervention\Image\Interfaces\SizeInterface;
use Intervention\Image\Modifiers\FillModifier;
/**
* @method SizeInterface getCropSize(ImageInterface $image)
@@ -27,9 +27,10 @@ class ContainModifier extends SpecializedModifier
$crop = $this->getCropSize($image);
$resize = $this->getResizeSize($image);
$background = $this->driver()->handleInput($this->background);
$blendingColor = $image->blendingColor();
foreach ($image as $frame) {
$this->modify($frame, $crop, $resize, $background);
$this->modify($frame, $crop, $resize, $background, $blendingColor);
}
return $image;
@@ -39,26 +40,19 @@ class ContainModifier extends SpecializedModifier
FrameInterface $frame,
SizeInterface $crop,
SizeInterface $resize,
ColorInterface $background
ColorInterface $background,
ColorInterface $blendingColor
): void {
// create new gd image
$modified = $this->driver()->createImage(
$resize->width(),
$resize->height()
)->modify(
new FillModifier($background)
)->core()->native();
// retain resolution
$this->copyResolution($frame->native(), $modified);
$modified = Cloner::cloneEmpty($frame->native(), $resize, $background);
// make image area transparent to keep transparency
// even if background-color is set
$transparent = imagecolorallocatealpha(
$modified,
$background->channel(Red::class)->value(),
$background->channel(Green::class)->value(),
$background->channel(Blue::class)->value(),
$blendingColor->channel(Red::class)->value(),
$blendingColor->channel(Green::class)->value(),
$blendingColor->channel(Blue::class)->value(),
127,
);
imagealphablending($modified, false); // do not blend / just overwrite

View File

@@ -2,6 +2,7 @@
namespace Intervention\Image\Drivers\Gd\Modifiers;
use Intervention\Image\Drivers\Gd\Cloner;
use Intervention\Image\Drivers\Gd\SpecializedModifier;
use Intervention\Image\Interfaces\FrameInterface;
use Intervention\Image\Interfaces\ImageInterface;
@@ -28,31 +29,12 @@ class CoverModifier extends SpecializedModifier
protected function modifyFrame(FrameInterface $frame, SizeInterface $crop, SizeInterface $resize): void
{
// create new image
$modified = $this->driver()->createImage(
$resize->width(),
$resize->height()
)->core()->native();
// get original image
$original = $frame->native();
// retain resolution
$this->copyResolution($original, $modified);
// preserve transparency
$transIndex = imagecolortransparent($original);
if ($transIndex != -1) {
$rgba = imagecolorsforindex($modified, $transIndex);
$transColor = imagecolorallocatealpha($modified, $rgba['red'], $rgba['green'], $rgba['blue'], 127);
imagefill($modified, 0, 0, $transColor);
imagecolortransparent($modified, $transColor);
}
$modified = Cloner::cloneEmpty($frame->native(), $resize);
// copy content from resource
imagecopyresampled(
$modified,
$original,
$frame->native(),
0,
0,
$crop->pivot()->x(),

View File

@@ -2,6 +2,7 @@
namespace Intervention\Image\Drivers\Gd\Modifiers;
use Intervention\Image\Drivers\Gd\Cloner;
use Intervention\Image\Drivers\Gd\SpecializedModifier;
use Intervention\Image\Interfaces\FrameInterface;
use Intervention\Image\Interfaces\ImageInterface;
@@ -28,31 +29,12 @@ class CropModifier extends SpecializedModifier
protected function cropFrame(FrameInterface $frame, SizeInterface $resizeTo): void
{
// create new image
$modified = $this->driver()
->createImage($resizeTo->width(), $resizeTo->height())
->core()
->native();
// get original image
$original = $frame->native();
// retain resolution
$this->copyResolution($original, $modified);
// preserve transparency
$transIndex = imagecolortransparent($original);
if ($transIndex != -1) {
$rgba = imagecolorsforindex($modified, $transIndex);
$transColor = imagecolorallocatealpha($modified, $rgba['red'], $rgba['green'], $rgba['blue'], 127);
imagefill($modified, 0, 0, $transColor);
imagecolortransparent($modified, $transColor);
}
$modified = Cloner::cloneEmpty($frame->native(), $resizeTo);
// copy content from resource
imagecopyresampled(
$modified,
$original,
$frame->native(),
0,
0,
$resizeTo->pivot()->x() + $this->offset_x,

View File

@@ -2,6 +2,7 @@
namespace Intervention\Image\Drivers\Gd\Modifiers;
use Intervention\Image\Drivers\Gd\Cloner;
use Intervention\Image\Drivers\Gd\SpecializedModifier;
use Intervention\Image\Exceptions\InputException;
use Intervention\Image\Interfaces\ImageInterface;
@@ -33,10 +34,7 @@ class QuantizeColorsModifier extends SpecializedModifier
foreach ($image as $frame) {
// create new image for color quantization
$reduced = imagecreatetruecolor($width, $height);
// retain resolution
$this->copyResolution($frame->native(), $reduced);
$reduced = Cloner::cloneEmpty($frame->native(), background: $image->blendingColor());
// fill with background
imagefill($reduced, 0, 0, $background);

View File

@@ -5,6 +5,7 @@ namespace Intervention\Image\Drivers\Gd\Modifiers;
use Intervention\Image\Colors\Rgb\Channels\Blue;
use Intervention\Image\Colors\Rgb\Channels\Green;
use Intervention\Image\Colors\Rgb\Channels\Red;
use Intervention\Image\Drivers\Gd\Cloner;
use Intervention\Image\Drivers\Gd\SpecializedModifier;
use Intervention\Image\Interfaces\ColorInterface;
use Intervention\Image\Interfaces\FrameInterface;
@@ -35,16 +36,8 @@ class ResizeCanvasModifier extends SpecializedModifier
SizeInterface $resize,
ColorInterface $background,
): void {
// create new gd image
$modified = $this->driver()->createImage(
$resize->width(),
$resize->height()
)->modify(
new FillModifier($background)
)->core()->native();
// retain resolution
$this->copyResolution($frame->native(), $modified);
// create new canvas with target size & target background color
$modified = Cloner::cloneEmpty($frame->native(), $resize, $background);
// make image area transparent to keep transparency
// even if background-color is set
@@ -57,7 +50,7 @@ class ResizeCanvasModifier extends SpecializedModifier
);
imagealphablending($modified, false); // do not blend / just overwrite
imagecolortransparent($modified, $transparent);
// imagecolortransparent($modified, $transparent);
imagefilledrectangle(
$modified,
$resize->pivot()->x() * -1,

View File

@@ -2,6 +2,7 @@
namespace Intervention\Image\Drivers\Gd\Modifiers;
use Intervention\Image\Drivers\Gd\Cloner;
use Intervention\Image\Drivers\Gd\SpecializedModifier;
use Intervention\Image\Interfaces\FrameInterface;
use Intervention\Image\Interfaces\ImageInterface;
@@ -25,35 +26,13 @@ class ResizeModifier extends SpecializedModifier
private function resizeFrame(FrameInterface $frame, SizeInterface $resizeTo): void
{
// create new image
$modified = imagecreatetruecolor(
$resizeTo->width(),
$resizeTo->height()
);
// get current GDImage
$current = $frame->native();
// retain resolution
$this->copyResolution($current, $modified);
// preserve transparency
$transIndex = imagecolortransparent($current);
if ($transIndex != -1) {
$rgba = imagecolorsforindex($modified, $transIndex);
$transColor = imagecolorallocatealpha($modified, $rgba['red'], $rgba['green'], $rgba['blue'], 127);
imagefill($modified, 0, 0, $transColor);
imagecolortransparent($modified, $transColor);
} else {
imagealphablending($modified, false);
imagesavealpha($modified, true);
}
// create empty canvas in target size
$modified = Cloner::cloneEmpty($frame->native(), $resizeTo);
// copy content from resource
imagecopyresampled(
$modified,
$current,
$frame->native(),
$resizeTo->pivot()->x(),
$resizeTo->pivot()->y(),
0,

View File

@@ -5,6 +5,7 @@ namespace Intervention\Image\Drivers\Gd\Modifiers;
use Intervention\Image\Colors\Rgb\Channels\Blue;
use Intervention\Image\Colors\Rgb\Channels\Green;
use Intervention\Image\Colors\Rgb\Channels\Red;
use Intervention\Image\Drivers\Gd\Cloner;
use Intervention\Image\Drivers\Gd\SpecializedModifier;
use Intervention\Image\Geometry\Rectangle;
use Intervention\Image\Interfaces\ColorInterface;
@@ -74,15 +75,7 @@ class RotateModifier extends SpecializedModifier
->rotate($this->rotationAngle() * -1);
// create new gd image
$modified = $this->driver()->createImage(
imagesx($rotated),
imagesy($rotated)
)->modify(new FillModifier($background))
->core()
->native();
// retain resolution
$this->copyResolution($frame->native(), $modified);
$modified = Cloner::cloneEmpty($frame->native(), $container, $background);
// draw the cutout on new gd image to have a transparent
// background where the rotated image will be placed

View File

@@ -2,16 +2,8 @@
namespace Intervention\Image\Drivers\Gd;
use GdImage;
use Intervention\Image\Drivers\DriverSpecializedModifier;
abstract class SpecializedModifier extends DriverSpecializedModifier
{
protected function copyResolution(GdImage $source, GdImage $target): void
{
$resolution = imageresolution($source);
if (is_array($resolution) && array_key_exists(0, $resolution) && array_key_exists(1, $resolution)) {
imageresolution($target, $resolution[0], $resolution[1]);
}
}
}

View File

@@ -17,15 +17,21 @@ class JpegEncoder extends DriverSpecializedEncoder
$format = 'jpeg';
$compression = Imagick::COMPRESSION_JPEG;
// resolve blending color because jpeg has no transparency
$background = $this->driver()
->colorProcessor($image->colorspace())
->colorToNative($image->blendingColor());
$imagick = $image->core()->native();
$imagick->setImageBackgroundColor('white');
$imagick->setBackgroundColor('white');
$imagick->setImageBackgroundColor($background);
$imagick->setBackgroundColor($background);
$imagick->setFormat($format);
$imagick->setImageFormat($format);
$imagick->setCompression($compression);
$imagick->setImageCompression($compression);
$imagick->setCompressionQuality($this->quality);
$imagick->setImageCompressionQuality($this->quality);
$imagick->setImageAlphaChannel(Imagick::ALPHACHANNEL_REMOVE);
return new EncodedImage($imagick->getImagesBlob(), 'image/jpeg');
}

View File

@@ -3,6 +3,7 @@
namespace Intervention\Image\Drivers\Imagick;
use Imagick;
use ImagickPixel;
use Intervention\Image\Geometry\Rectangle;
use Intervention\Image\Image;
use Intervention\Image\Interfaces\DriverInterface;
@@ -14,6 +15,9 @@ class Frame implements FrameInterface
{
public function __construct(protected Imagick $native)
{
$background = new ImagickPixel('rgba(255, 255, 255, 0)');
$this->native->setImageBackgroundColor($background);
$this->native->setBackgroundColor($background);
}
/**

View File

@@ -11,6 +11,7 @@ use Intervention\Image\Analyzers\PixelColorsAnalyzer;
use Intervention\Image\Analyzers\ProfileAnalyzer;
use Intervention\Image\Analyzers\ResolutionAnalyzer;
use Intervention\Image\Analyzers\WidthAnalyzer;
use Intervention\Image\Colors\Rgb\Color;
use Intervention\Image\Encoders\AutoEncoder;
use Intervention\Image\Encoders\AvifEncoder;
use Intervention\Image\Encoders\BmpEncoder;
@@ -92,6 +93,14 @@ final class Image implements ImageInterface
*/
protected Origin $origin;
/**
* Color is mixed with transparent areas when converting to a format which
* does not support transparency.
*
* @var ColorInterface
*/
protected ColorInterface $blendingColor;
/**
* Create new instance
*
@@ -106,6 +115,9 @@ final class Image implements ImageInterface
protected CollectionInterface $exif = new Collection()
) {
$this->origin = new Origin();
$this->blendingColor = $this->colorspace()->importColor(
new Color(255, 255, 255, 0)
);
}
/**
@@ -368,6 +380,28 @@ final class Image implements ImageInterface
return $this->analyze(new PixelColorsAnalyzer($x, $y));
}
/**
* {@inheritdoc}
*
* @see ImageInterface::blendingColor()
*/
public function blendingColor(): ColorInterface
{
return $this->blendingColor;
}
/**
* {@inheritdoc}
*
* @see ImageInterface::setBlendingColor()
*/
public function setBlendingColor(mixed $color): ImageInterface
{
$this->blendingColor = $this->driver()->handleInput($color);
return $this;
}
/**
* {@inheritdoc}
*

View File

@@ -185,6 +185,23 @@ interface ImageInterface extends IteratorAggregate, Countable
*/
public function pickColors(int $x, int $y): CollectionInterface;
/**
* Return color that is mixed with transparent areas when converting to a format which
* does not support transparency.
*
* @return ColorInterface
*/
public function blendingColor(): ColorInterface;
/**
* Set blending color will have no effect unless image is converted into a format
* which does not support transparency.
*
* @param mixed $color
* @return ImageInterface
*/
public function setBlendingColor(mixed $color): ImageInterface;
/**
* Retrieve ICC color profile of image
*

View File

@@ -0,0 +1,69 @@
<?php
namespace Intervention\Image\Tests\Drivers\Gd;
use Intervention\Image\Colors\Rgb\Color;
use Intervention\Image\Drivers\Gd\Cloner;
use Intervention\Image\Geometry\Rectangle;
use Intervention\Image\Tests\TestCase;
class ClonerTest extends TestCase
{
public function testClone(): void
{
$gd = imagecreatefromgif($this->getTestImagePath('gradient.gif'));
$clone = Cloner::clone($gd);
$this->assertEquals(16, imagesx($gd));
$this->assertEquals(16, imagesy($gd));
$this->assertEquals(16, imagesx($clone));
$this->assertEquals(16, imagesy($clone));
$this->assertEquals(
imagecolorsforindex($gd, imagecolorat($gd, 10, 10)),
imagecolorsforindex($clone, imagecolorat($clone, 10, 10))
);
}
public function testCloneEmpty(): void
{
$gd = imagecreatefromgif($this->getTestImagePath('gradient.gif'));
$clone = Cloner::cloneEmpty($gd, new Rectangle(12, 12), new Color(255, 0, 0, 0));
$this->assertEquals(16, imagesx($gd));
$this->assertEquals(16, imagesy($gd));
$this->assertEquals(12, imagesx($clone));
$this->assertEquals(12, imagesy($clone));
$this->assertEquals(
['red' => 0, 'green' => 255, 'blue' => 2, 'alpha' => 0],
imagecolorsforindex($gd, imagecolorat($gd, 10, 10)),
);
$this->assertEquals(
['red' => 255, 'green' => 0, 'blue' => 0, 'alpha' => 127],
imagecolorsforindex($clone, imagecolorat($clone, 10, 10))
);
}
public function testCLoneBlended(): void
{
$gd = imagecreatefromgif($this->getTestImagePath('gradient.gif'));
$clone = Cloner::cloneBlended($gd, new Color(255, 0, 255, 255));
$this->assertEquals(16, imagesx($gd));
$this->assertEquals(16, imagesy($gd));
$this->assertEquals(16, imagesx($clone));
$this->assertEquals(16, imagesy($clone));
$this->assertEquals(
['red' => 0, 'green' => 0, 'blue' => 0, 'alpha' => 127],
imagecolorsforindex($gd, imagecolorat($gd, 1, 0)),
);
$this->assertEquals(
['red' => 255, 'green' => 0, 'blue' => 255, 'alpha' => 0],
imagecolorsforindex($clone, imagecolorat($clone, 1, 0))
);
}
}

View File

@@ -4,6 +4,7 @@ namespace Intervention\Image\Tests\Drivers\Gd;
use Intervention\Image\Analyzers\WidthAnalyzer;
use Intervention\Image\Collection;
use Intervention\Image\Colors\Rgb\Color;
use Intervention\Image\Drivers\Gd\Core;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\Drivers\Gd\Frame;
@@ -53,10 +54,10 @@ class ImageTest extends TestCase
$this->assertEquals(4, $result->width());
$this->assertEquals('ff0000', $image->pickColor(0, 0)->toHex());
$this->assertEquals('00000000', $image->pickColor(1, 0)->toHex());
$this->assertTransparency($image->pickColor(1, 0));
$this->assertEquals('ff0000', $clone->pickColor(0, 0)->toHex());
$this->assertEquals('00000000', $clone->pickColor(1, 0)->toHex());
$this->assertTransparency($image->pickColor(1, 0));
}
public function testDriver(): void
@@ -210,4 +211,14 @@ class ImageTest extends TestCase
{
$this->assertInstanceOf(Image::class, $this->image->text('test', 0, 0, new Font()));
}
public function testSetGetBlendingColor(): void
{
$image = $this->readTestImage('gradient.gif');
$this->assertInstanceOf(ColorInterface::class, $image->blendingColor());
$this->assertColor(255, 255, 255, 0, $image->blendingColor());
$result = $image->setBlendingColor(new Color(1, 2, 3, 4));
$this->assertColor(1, 2, 3, 4, $result->blendingColor());
$this->assertColor(1, 2, 3, 4, $image->blendingColor());
}
}

View File

@@ -23,7 +23,7 @@ class ContainModifierTest extends TestCase
$this->assertEquals(200, $image->width());
$this->assertEquals(100, $image->height());
$this->assertColor(255, 255, 0, 255, $image->pickColor(0, 0));
$this->assertColor(255, 255, 0, 0, $image->pickColor(140, 10)); // transparent
$this->assertTransparency($image->pickColor(140, 10));
$this->assertColor(255, 255, 0, 255, $image->pickColor(175, 10));
}
}

View File

@@ -21,7 +21,7 @@ class FlipFlopModifierTest extends TestCase
$image = $this->readTestImage('tile.png');
$this->assertEquals('b4e000', $image->pickColor(0, 0)->toHex());
$image->modify(new FlipModifier());
$this->assertEquals('00000000', $image->pickColor(0, 0)->toHex());
$this->assertTransparency($image->pickColor(0, 0));
}
public function testFlopImage(): void
@@ -29,6 +29,6 @@ class FlipFlopModifierTest extends TestCase
$image = $this->readTestImage('tile.png');
$this->assertEquals('b4e000', $image->pickColor(0, 0)->toHex());
$image->modify(new FlopModifier());
$this->assertEquals('00000000', $image->pickColor(0, 0)->toHex());
$this->assertTransparency($image->pickColor(0, 0));
}
}

View File

@@ -5,6 +5,7 @@ namespace Intervention\Image\Tests\Drivers\Imagick;
use Imagick;
use Intervention\Image\Analyzers\WidthAnalyzer;
use Intervention\Image\Collection;
use Intervention\Image\Colors\Rgb\Color;
use Intervention\Image\Drivers\Imagick\Core;
use Intervention\Image\Drivers\Imagick\Driver;
use Intervention\Image\Drivers\Imagick\Frame;
@@ -204,4 +205,14 @@ class ImageTest extends TestCase
{
$this->assertInstanceOf(Image::class, $this->image->sharpen(12));
}
public function testSetGetBlendingColor(): void
{
$image = $this->readTestImage('gradient.gif');
$this->assertInstanceOf(ColorInterface::class, $image->blendingColor());
$this->assertColor(255, 255, 255, 0, $image->blendingColor());
$result = $image->setBlendingColor(new Color(1, 2, 3, 4));
$this->assertColor(1, 2, 3, 4, $result->blendingColor());
$this->assertColor(1, 2, 3, 4, $image->blendingColor());
}
}