1
0
mirror of https://github.com/Intervention/image.git synced 2025-08-01 11:30:16 +02:00

Fix transparency issues with animated GIF & rotation

This commit is contained in:
Oliver Vogel
2023-11-12 10:48:19 +01:00
parent 6167e8e233
commit 2960c31611
2 changed files with 21 additions and 13 deletions

View File

@@ -3,6 +3,7 @@
namespace Intervention\Image\Drivers\Gd;
use Intervention\Image\Collection;
use Intervention\Image\Colors\Rgb\Channels\Alpha;
use Intervention\Image\Drivers\Gd\Frame;
use Intervention\Image\Drivers\Gd\Image;
use Intervention\Image\Drivers\Gd\Traits\CanHandleColors;
@@ -72,13 +73,18 @@ class Factory implements FactoryInterface
{
$core = imagecreatetruecolor($width, $height);
imagesavealpha($core, true);
$color = match (is_null($background)) {
true => imagecolorallocatealpha($core, 255, 0, 255, 127),
default => $this->allocateColor($core, $background),
};
imagealphablending($core, false);
imagefill($core, 0, 0, $color);
imagesavealpha($core, true);
if ($background && $background->channel(Alpha::class)->value() == 0) {
imagecolortransparent($core, $color);
}
return $core;
}

View File

@@ -46,17 +46,23 @@ class RotateModifier extends AbstractRotateModifier implements ModifierInterface
*/
protected function modify(FrameInterface $frame, ColorInterface $background): void
{
// rotate original image against transparent background
$rotated = imagerotate(
$frame->core(),
$this->rotationAngle(),
imagecolorallocatealpha(
// get transparent color from frame core
$transparent = match ($transparent = imagecolortransparent($frame->core())) {
-1 => imagecolorallocatealpha(
$frame->core(),
$background->channel(Red::class)->value(),
$background->channel(Green::class)->value(),
$background->channel(Blue::class)->value(),
127
)
),
default => $transparent,
};
// rotate original image against transparent background
$rotated = imagerotate(
$frame->core(),
$this->rotationAngle(),
$transparent
);
// create size from original after rotation
@@ -74,24 +80,20 @@ class RotateModifier extends AbstractRotateModifier implements ModifierInterface
->valign('center')
->rotate($this->rotationAngle() * -1);
// create new gd image
// create new gd core
$modified = $this->imageFactory()->newCore(
imagesx($rotated),
imagesy($rotated),
$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
// background where the rotated image will be placed
imagealphablending($modified, false);
imagefilledpolygon(
$modified,
$cutout->toArray(),
$transparent
imagecolortransparent($modified)
);
// place rotated image on new gd image