Файл: vendor/intervention/image/src/Drivers/Gd/Modifiers/RotateModifier.php
Строк: 192
<?php
declare(strict_types=1);
namespace InterventionImageDriversGdModifiers;
use InterventionImageAlignment;
use InterventionImageColorsRgbColor as RgbColor;
use InterventionImageColorsRgbColorspace as Rgb;
use InterventionImageDriversGdCloner;
use InterventionImageExceptionsDriverException;
use InterventionImageExceptionsInvalidArgumentException;
use InterventionImageExceptionsModifierException;
use InterventionImageExceptionsStateException;
use InterventionImageGeometryPolygon;
use InterventionImageInterfacesColorInterface;
use InterventionImageInterfacesFrameInterface;
use InterventionImageInterfacesImageInterface;
use InterventionImageInterfacesSpecializedInterface;
use InterventionImageModifiersRotateModifier as GenericRotateModifier;
use InterventionImageSize;
class RotateModifier extends GenericRotateModifier implements SpecializedInterface
{
/**
* {@inheritdoc}
*
* @see ModifierInterface::apply()
*
* @throws InvalidArgumentException
* @throws ModifierException
* @throws StateException
* @throws DriverException
*/
public function apply(ImageInterface $image): ImageInterface
{
$background = $this->backgroundColor();
foreach ($image as $frame) {
$this->modifyFrame($frame, $background);
}
return $image;
}
/**
* Apply rotation modification on given frame, given background
* color is used for newly create image areas
*
* @throws InvalidArgumentException
* @throws ModifierException
* @throws DriverException
*/
protected function modifyFrame(FrameInterface $frame, ColorInterface $background): void
{
// normalize color to rgb colorspace
$background = $background->toColorspace(Rgb::class);
if (!$background instanceof RgbColor) {
throw new ModifierException('Failed to normalize background color to RGB color space');
}
// get transparent color from frame core
$transparent = match ($transparent = imagecolortransparent($frame->native())) {
-1 => imagecolorallocatealpha(
$frame->native(),
$background->red()->value(),
$background->green()->value(),
$background->blue()->value(),
127,
),
default => $transparent,
};
// rotate original image against transparent background
$rotated = imagerotate(
$frame->native(),
$this->rotationAngle() * -1,
$transparent,
);
// create size from original after rotation
$container = (new Size(
imagesx($rotated),
imagesy($rotated),
))->movePivot(Alignment::CENTER);
// create size from original and rotate points
$cutout = Polygon::fromSize(new Size(
imagesx($frame->native()),
imagesy($frame->native()),
$container->pivot(),
))->alignHorizontally(Alignment::CENTER)
->alignVertically(Alignment::CENTER)
->rotate($this->rotationAngle());
// create new gd image
$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
imagealphablending($modified, false);
imagefilledpolygon(
$modified,
$cutout->toArray(),
imagecolortransparent($modified),
);
// place rotated image on new gd image
imagealphablending($modified, true);
imagecopy(
$modified,
$rotated,
0,
0,
0,
0,
imagesx($rotated),
imagesy($rotated),
);
$frame->setNative($modified);
}
}