class Rotate

Same name and namespace in other branches
  1. 8.9.x core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Rotate.php \Drupal\system\Plugin\ImageToolkit\Operation\gd\Rotate
  2. 10 core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Rotate.php \Drupal\system\Plugin\ImageToolkit\Operation\gd\Rotate
  3. 11.x core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Rotate.php \Drupal\system\Plugin\ImageToolkit\Operation\gd\Rotate

Defines GD2 rotate operation.

Plugin annotation


@ImageToolkitOperation(
  id = "gd_rotate",
  toolkit = "gd",
  operation = "rotate",
  label = @Translation("Rotate"),
  description = @Translation("Rotates an image by the given number of degrees.")
)

Hierarchy

Expanded class hierarchy of Rotate

5 string references to 'Rotate'
ImageEffectsTest::testRotateEffect in core/modules/image/tests/src/Kernel/ImageEffectsTest.php
Tests the image_rotate_effect() function.
ImageTest::testRotate in core/tests/Drupal/Tests/Core/Image/ImageTest.php
Tests \Drupal\Core\Image\Image::rotate().
ToolkitGdTest::providerTestImageFiles in core/tests/Drupal/KernelTests/Core/Image/ToolkitGdTest.php
Data provider for ::testManipulations().
ToolkitTestBase::assertToolkitOperationsCalled in core/tests/Drupal/FunctionalTests/Image/ToolkitTestBase.php
Tests that only allowed image toolkit operations are called.
ToolkitTestTrait::assertToolkitOperationsCalled in core/tests/Drupal/Tests/Traits/Core/Image/ToolkitTestTrait.php
Assert that all of the specified image toolkit operations were called once.

File

core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Rotate.php, line 18

Namespace

Drupal\system\Plugin\ImageToolkit\Operation\gd
View source
class Rotate extends GDImageToolkitOperationBase {
    
    /**
     * {@inheritdoc}
     */
    protected function arguments() {
        return [
            'degrees' => [
                'description' => 'The number of (clockwise) degrees to rotate the image',
            ],
            'background' => [
                'description' => "A string specifying the hexadecimal color code to use as background for the uncovered area of the image after the rotation. E.g. '#000000' for black, '#ff00ff' for magenta, and '#ffffff' for white. For images that support transparency, this will default to transparent white",
                'required' => FALSE,
                'default' => NULL,
            ],
        ];
    }
    
    /**
     * {@inheritdoc}
     */
    protected function validateArguments(array $arguments) {
        // PHP 5.5 GD bug: https://bugs.php.net/bug.php?id=65148: To prevent buggy
        // behavior on negative multiples of 90 degrees we convert any negative
        // angle to a positive one between 0 and 360 degrees.
        $arguments['degrees'] -= floor($arguments['degrees'] / 360) * 360;
        // Validate or set background color argument.
        if (!empty($arguments['background'])) {
            // Validate the background color: Color::hexToRgb does so for us.
            $background = Color::hexToRgb($arguments['background']) + [
                'alpha' => 0,
            ];
        }
        else {
            // Background color is not specified: use transparent white as background.
            $background = [
                'red' => 255,
                'green' => 255,
                'blue' => 255,
                'alpha' => 127,
            ];
        }
        // Store the color index for the background as that is what GD uses.
        $arguments['background_idx'] = imagecolorallocatealpha($this->getToolkit()
            ->getResource(), $background['red'], $background['green'], $background['blue'], $background['alpha']);
        if ($this->getToolkit()
            ->getType() === IMAGETYPE_GIF) {
            // GIF does not work with a transparency channel, but can define 1 color
            // in its palette to act as transparent.
            // Get the current transparent color, if any.
            $gif_transparent_id = imagecolortransparent($this->getToolkit()
                ->getResource());
            if ($gif_transparent_id !== -1) {
                // The gif already has a transparent color set: remember it to set it on
                // the rotated image as well.
                $arguments['gif_transparent_color'] = imagecolorsforindex($this->getToolkit()
                    ->getResource(), $gif_transparent_id);
                if ($background['alpha'] >= 127) {
                    // We want a transparent background: use the color already set to act
                    // as transparent, as background.
                    $arguments['background_idx'] = $gif_transparent_id;
                }
            }
            else {
                // The gif does not currently have a transparent color set.
                if ($background['alpha'] >= 127) {
                    // But as the background is transparent, it should get one.
                    $arguments['gif_transparent_color'] = $background;
                }
            }
        }
        return $arguments;
    }
    
    /**
     * {@inheritdoc}
     */
    protected function execute(array $arguments) {
        // PHP installations using non-bundled GD do not have imagerotate.
        if (!function_exists('imagerotate')) {
            $this->logger
                ->notice('The image %file could not be rotated because the imagerotate() function is not available in this PHP installation.', [
                '%file' => $this->getToolkit()
                    ->getSource(),
            ]);
            return FALSE;
        }
        // Stores the original GD resource.
        $original_res = $this->getToolkit()
            ->getResource();
        if ($new_res = imagerotate($this->getToolkit()
            ->getResource(), 360 - $arguments['degrees'], $arguments['background_idx'])) {
            $this->getToolkit()
                ->setResource($new_res);
            imagedestroy($original_res);
            // GIFs need to reassign the transparent color after performing the
            // rotate, but only do so, if the image already had transparency of its
            // own, or the rotate added a transparent background.
            if (!empty($arguments['gif_transparent_color'])) {
                $transparent_idx = imagecolorexactalpha($this->getToolkit()
                    ->getResource(), $arguments['gif_transparent_color']['red'], $arguments['gif_transparent_color']['green'], $arguments['gif_transparent_color']['blue'], $arguments['gif_transparent_color']['alpha']);
                imagecolortransparent($this->getToolkit()
                    ->getResource(), $transparent_idx);
            }
            return TRUE;
        }
        return FALSE;
    }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title Overrides
GDImageToolkitOperationBase::getToolkit protected function The correctly typed image toolkit for GD operations. Overrides ImageToolkitOperationBase::getToolkit
ImageToolkitOperationBase::$logger protected property A logger instance.
ImageToolkitOperationBase::$toolkit protected property The image toolkit.
ImageToolkitOperationBase::apply final public function Applies a toolkit specific operation to an image. Overrides ImageToolkitOperationInterface::apply
ImageToolkitOperationBase::prepareArguments protected function Checks for required arguments and adds optional argument defaults.
ImageToolkitOperationBase::__construct public function Constructs an image toolkit operation plugin.
PluginInspectionInterface::getPluginDefinition public function Gets the definition of the plugin implementation. 6
PluginInspectionInterface::getPluginId public function Gets the plugin_id of the plugin instance. 2
Rotate::arguments protected function Returns the definition of the operation arguments. Overrides ImageToolkitOperationBase::arguments
Rotate::execute protected function Performs the actual manipulation on the image. Overrides ImageToolkitOperationBase::execute
Rotate::validateArguments protected function Validates the arguments. Overrides ImageToolkitOperationBase::validateArguments

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.