mirror of
https://github.com/Intervention/image.git
synced 2025-08-19 12:11:26 +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();
|
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;
|
namespace Intervention\Image\Drivers\Gd;
|
||||||
|
|
||||||
|
use GdImage;
|
||||||
use Intervention\Image\Drivers\AbstractDriver;
|
use Intervention\Image\Drivers\AbstractDriver;
|
||||||
use Intervention\Image\Image;
|
use Intervention\Image\Image;
|
||||||
use Intervention\Image\Interfaces\ColorInterface;
|
use Intervention\Image\Interfaces\ColorInterface;
|
||||||
|
@@ -99,4 +99,43 @@ class Frame implements FrameInterface
|
|||||||
|
|
||||||
return $this;
|
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());
|
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));
|
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\Analyzers\WidthAnalyzer;
|
||||||
use Intervention\Image\Collection;
|
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\Core;
|
||||||
use Intervention\Image\Drivers\Gd\Driver;
|
use Intervention\Image\Drivers\Gd\Driver;
|
||||||
use Intervention\Image\Drivers\Gd\Frame;
|
use Intervention\Image\Drivers\Gd\Frame;
|
||||||
@@ -17,10 +21,13 @@ use Intervention\Image\Interfaces\ResolutionInterface;
|
|||||||
use Intervention\Image\Interfaces\SizeInterface;
|
use Intervention\Image\Interfaces\SizeInterface;
|
||||||
use Intervention\Image\Modifiers\GreyscaleModifier;
|
use Intervention\Image\Modifiers\GreyscaleModifier;
|
||||||
use Intervention\Image\Tests\TestCase;
|
use Intervention\Image\Tests\TestCase;
|
||||||
|
use Intervention\Image\Tests\Traits\CanCreateGdTestImage;
|
||||||
use Intervention\Image\Typography\Font;
|
use Intervention\Image\Typography\Font;
|
||||||
|
|
||||||
class ImageTest extends TestCase
|
class ImageTest extends TestCase
|
||||||
{
|
{
|
||||||
|
use CanCreateGdTestImage;
|
||||||
|
|
||||||
protected Image $image;
|
protected Image $image;
|
||||||
|
|
||||||
public function setUp(): void
|
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
|
public function testDriver(): void
|
||||||
{
|
{
|
||||||
$this->assertInstanceOf(Driver::class, $this->image->driver());
|
$this->assertInstanceOf(Driver::class, $this->image->driver());
|
||||||
|
@@ -3,6 +3,11 @@
|
|||||||
namespace Intervention\Image\Tests\Drivers\Imagick;
|
namespace Intervention\Image\Tests\Drivers\Imagick;
|
||||||
|
|
||||||
use 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\Analyzers\WidthAnalyzer;
|
||||||
use Intervention\Image\Collection;
|
use Intervention\Image\Collection;
|
||||||
use Intervention\Image\Drivers\Imagick\Core;
|
use Intervention\Image\Drivers\Imagick\Core;
|
||||||
@@ -18,9 +23,12 @@ use Intervention\Image\Interfaces\ResolutionInterface;
|
|||||||
use Intervention\Image\Interfaces\SizeInterface;
|
use Intervention\Image\Interfaces\SizeInterface;
|
||||||
use Intervention\Image\Modifiers\GreyscaleModifier;
|
use Intervention\Image\Modifiers\GreyscaleModifier;
|
||||||
use Intervention\Image\Tests\TestCase;
|
use Intervention\Image\Tests\TestCase;
|
||||||
|
use Intervention\Image\Tests\Traits\CanCreateImagickTestImage;
|
||||||
|
|
||||||
class ImageTest extends TestCase
|
class ImageTest extends TestCase
|
||||||
{
|
{
|
||||||
|
use CanCreateImagickTestImage;
|
||||||
|
|
||||||
protected Image $image;
|
protected Image $image;
|
||||||
|
|
||||||
public function setUp(): void
|
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
|
public function testDriver(): void
|
||||||
{
|
{
|
||||||
$this->assertInstanceOf(Driver::class, $this->image->driver());
|
$this->assertInstanceOf(Driver::class, $this->image->driver());
|
||||||
|
Reference in New Issue
Block a user