mirror of
https://github.com/Intervention/image.git
synced 2025-08-05 13:27:29 +02:00
Fix transparency issues with animated GIF & rotation
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
namespace Intervention\Image\Drivers\Gd;
|
namespace Intervention\Image\Drivers\Gd;
|
||||||
|
|
||||||
use Intervention\Image\Collection;
|
use Intervention\Image\Collection;
|
||||||
|
use Intervention\Image\Colors\Rgb\Channels\Alpha;
|
||||||
use Intervention\Image\Drivers\Gd\Frame;
|
use Intervention\Image\Drivers\Gd\Frame;
|
||||||
use Intervention\Image\Drivers\Gd\Image;
|
use Intervention\Image\Drivers\Gd\Image;
|
||||||
use Intervention\Image\Drivers\Gd\Traits\CanHandleColors;
|
use Intervention\Image\Drivers\Gd\Traits\CanHandleColors;
|
||||||
@@ -72,13 +73,18 @@ class Factory implements FactoryInterface
|
|||||||
{
|
{
|
||||||
$core = imagecreatetruecolor($width, $height);
|
$core = imagecreatetruecolor($width, $height);
|
||||||
|
|
||||||
|
imagesavealpha($core, true);
|
||||||
|
|
||||||
$color = match (is_null($background)) {
|
$color = match (is_null($background)) {
|
||||||
true => imagecolorallocatealpha($core, 255, 0, 255, 127),
|
true => imagecolorallocatealpha($core, 255, 0, 255, 127),
|
||||||
default => $this->allocateColor($core, $background),
|
default => $this->allocateColor($core, $background),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
imagealphablending($core, false);
|
||||||
imagefill($core, 0, 0, $color);
|
imagefill($core, 0, 0, $color);
|
||||||
imagesavealpha($core, true);
|
if ($background && $background->channel(Alpha::class)->value() == 0) {
|
||||||
|
imagecolortransparent($core, $color);
|
||||||
|
}
|
||||||
|
|
||||||
return $core;
|
return $core;
|
||||||
}
|
}
|
||||||
|
@@ -46,17 +46,23 @@ class RotateModifier extends AbstractRotateModifier implements ModifierInterface
|
|||||||
*/
|
*/
|
||||||
protected function modify(FrameInterface $frame, ColorInterface $background): void
|
protected function modify(FrameInterface $frame, ColorInterface $background): void
|
||||||
{
|
{
|
||||||
// rotate original image against transparent background
|
// get transparent color from frame core
|
||||||
$rotated = imagerotate(
|
$transparent = match ($transparent = imagecolortransparent($frame->core())) {
|
||||||
$frame->core(),
|
-1 => imagecolorallocatealpha(
|
||||||
$this->rotationAngle(),
|
|
||||||
imagecolorallocatealpha(
|
|
||||||
$frame->core(),
|
$frame->core(),
|
||||||
$background->channel(Red::class)->value(),
|
$background->channel(Red::class)->value(),
|
||||||
$background->channel(Green::class)->value(),
|
$background->channel(Green::class)->value(),
|
||||||
$background->channel(Blue::class)->value(),
|
$background->channel(Blue::class)->value(),
|
||||||
127
|
127
|
||||||
)
|
),
|
||||||
|
default => $transparent,
|
||||||
|
};
|
||||||
|
|
||||||
|
// rotate original image against transparent background
|
||||||
|
$rotated = imagerotate(
|
||||||
|
$frame->core(),
|
||||||
|
$this->rotationAngle(),
|
||||||
|
$transparent
|
||||||
);
|
);
|
||||||
|
|
||||||
// create size from original after rotation
|
// create size from original after rotation
|
||||||
@@ -74,24 +80,20 @@ class RotateModifier extends AbstractRotateModifier implements ModifierInterface
|
|||||||
->valign('center')
|
->valign('center')
|
||||||
->rotate($this->rotationAngle() * -1);
|
->rotate($this->rotationAngle() * -1);
|
||||||
|
|
||||||
// create new gd image
|
// create new gd core
|
||||||
$modified = $this->imageFactory()->newCore(
|
$modified = $this->imageFactory()->newCore(
|
||||||
imagesx($rotated),
|
imagesx($rotated),
|
||||||
imagesy($rotated),
|
imagesy($rotated),
|
||||||
$background
|
$background
|
||||||
);
|
);
|
||||||
|
|
||||||
// define transparent colors
|
|
||||||
$transparent = imagecolorallocatealpha($modified, 255, 0, 255, 127);
|
|
||||||
imagecolortransparent($modified, $transparent);
|
|
||||||
|
|
||||||
// draw the cutout on new gd image to have a transparent
|
// draw the cutout on new gd image to have a transparent
|
||||||
// background where the rotated image will be placed
|
// background where the rotated image will be placed
|
||||||
imagealphablending($modified, false);
|
imagealphablending($modified, false);
|
||||||
imagefilledpolygon(
|
imagefilledpolygon(
|
||||||
$modified,
|
$modified,
|
||||||
$cutout->toArray(),
|
$cutout->toArray(),
|
||||||
$transparent
|
imagecolortransparent($modified)
|
||||||
);
|
);
|
||||||
|
|
||||||
// place rotated image on new gd image
|
// place rotated image on new gd image
|
||||||
|
Reference in New Issue
Block a user