mirror of
https://github.com/Intervention/image.git
synced 2025-08-18 19:51:22 +02:00
Merge branch 'feature/image-cloning'
This commit is contained in:
@@ -55,4 +55,11 @@ class Core extends Collection implements CoreInterface
|
||||
{
|
||||
return parent::last();
|
||||
}
|
||||
|
||||
public function __clone(): void
|
||||
{
|
||||
foreach ($this->items as $key => $frame) {
|
||||
$this->items[$key] = clone $frame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Intervention\Image\Drivers\Gd;
|
||||
|
||||
use GdImage;
|
||||
use Intervention\Image\Drivers\AbstractDriver;
|
||||
use Intervention\Image\Image;
|
||||
use Intervention\Image\Interfaces\ColorInterface;
|
||||
|
@@ -99,4 +99,43 @@ class Frame implements FrameInterface
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This workaround helps cloning GdImages which is currently not possible.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@@ -120,4 +120,9 @@ class Core implements CoreInterface, Iterator
|
||||
{
|
||||
return $this->frame($this->count());
|
||||
}
|
||||
|
||||
public function __clone(): void
|
||||
{
|
||||
$this->imagick = clone $this->imagick;
|
||||
}
|
||||
}
|
||||
|
@@ -774,4 +774,16 @@ final class Image implements ImageInterface, Countable
|
||||
{
|
||||
return $this->encode(new AvifEncoder($quality));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone image
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __clone(): void
|
||||
{
|
||||
$this->driver = clone $this->driver;
|
||||
$this->core = clone $this->core;
|
||||
$this->exif = clone $this->exif;
|
||||
}
|
||||
}
|
||||
|
@@ -4,6 +4,10 @@ namespace Intervention\Image\Tests\Drivers\Gd;
|
||||
|
||||
use Intervention\Image\Analyzers\WidthAnalyzer;
|
||||
use Intervention\Image\Collection;
|
||||
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\Drivers\Gd\Core;
|
||||
use Intervention\Image\Drivers\Gd\Driver;
|
||||
use Intervention\Image\Drivers\Gd\Frame;
|
||||
@@ -17,10 +21,13 @@ use Intervention\Image\Interfaces\ResolutionInterface;
|
||||
use Intervention\Image\Interfaces\SizeInterface;
|
||||
use Intervention\Image\Modifiers\GreyscaleModifier;
|
||||
use Intervention\Image\Tests\TestCase;
|
||||
use Intervention\Image\Tests\Traits\CanCreateGdTestImage;
|
||||
use Intervention\Image\Typography\Font;
|
||||
|
||||
class ImageTest extends TestCase
|
||||
{
|
||||
use CanCreateGdTestImage;
|
||||
|
||||
protected Image $image;
|
||||
|
||||
public function setUp(): void
|
||||
@@ -37,6 +44,25 @@ class ImageTest extends TestCase
|
||||
);
|
||||
}
|
||||
|
||||
public function testClone(): void
|
||||
{
|
||||
$image = $this->readTestImage('gradient.gif');
|
||||
$clone = clone $image;
|
||||
|
||||
$this->assertEquals(16, $image->width());
|
||||
$this->assertEquals(16, $clone->width());
|
||||
$result = $clone->crop(4, 4);
|
||||
$this->assertEquals(16, $image->width());
|
||||
$this->assertEquals(4, $clone->width());
|
||||
$this->assertEquals(4, $result->width());
|
||||
|
||||
$this->assertEquals('ff0000', $image->pickColor(0, 0)->toHex());
|
||||
$this->assertEquals('00000000', $image->pickColor(1, 0)->toHex());
|
||||
|
||||
$this->assertEquals('ff0000', $clone->pickColor(0, 0)->toHex());
|
||||
$this->assertEquals('00000000', $clone->pickColor(1, 0)->toHex());
|
||||
}
|
||||
|
||||
public function testDriver(): void
|
||||
{
|
||||
$this->assertInstanceOf(Driver::class, $this->image->driver());
|
||||
|
@@ -3,6 +3,11 @@
|
||||
namespace Intervention\Image\Tests\Drivers\Imagick;
|
||||
|
||||
use Imagick;
|
||||
use ImagickPixel;
|
||||
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\Analyzers\WidthAnalyzer;
|
||||
use Intervention\Image\Collection;
|
||||
use Intervention\Image\Drivers\Imagick\Core;
|
||||
@@ -18,9 +23,12 @@ use Intervention\Image\Interfaces\ResolutionInterface;
|
||||
use Intervention\Image\Interfaces\SizeInterface;
|
||||
use Intervention\Image\Modifiers\GreyscaleModifier;
|
||||
use Intervention\Image\Tests\TestCase;
|
||||
use Intervention\Image\Tests\Traits\CanCreateImagickTestImage;
|
||||
|
||||
class ImageTest extends TestCase
|
||||
{
|
||||
use CanCreateImagickTestImage;
|
||||
|
||||
protected Image $image;
|
||||
|
||||
public function setUp(): void
|
||||
@@ -36,6 +44,25 @@ class ImageTest extends TestCase
|
||||
);
|
||||
}
|
||||
|
||||
public function testClone(): void
|
||||
{
|
||||
$image = $this->readTestImage('gradient.gif');
|
||||
$clone = clone $image;
|
||||
|
||||
$this->assertEquals(16, $image->width());
|
||||
$this->assertEquals(16, $clone->width());
|
||||
$result = $clone->crop(4, 4);
|
||||
$this->assertEquals(16, $image->width());
|
||||
$this->assertEquals(4, $clone->width());
|
||||
$this->assertEquals(4, $result->width());
|
||||
|
||||
$this->assertEquals('ff0000', $image->pickColor(0, 0)->toHex());
|
||||
$this->assertEquals('00000000', $image->pickColor(1, 0)->toHex());
|
||||
|
||||
$this->assertEquals('ff0000', $clone->pickColor(0, 0)->toHex());
|
||||
$this->assertEquals('00000000', $clone->pickColor(1, 0)->toHex());
|
||||
}
|
||||
|
||||
public function testDriver(): void
|
||||
{
|
||||
$this->assertInstanceOf(Driver::class, $this->image->driver());
|
||||
|
Reference in New Issue
Block a user