diff --git a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Rotate.php b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Rotate.php index e567ea4..1c51af2 100644 --- a/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Rotate.php +++ b/core/modules/system/src/Plugin/ImageToolkit/Operation/gd/Rotate.php @@ -3,6 +3,7 @@ namespace Drupal\system\Plugin\ImageToolkit\Operation\gd; use Drupal\Component\Utility\Color; +use Drupal\Component\Utility\Rectangle; /** * Defines GD2 rotate operation. @@ -96,6 +97,13 @@ protected function execute(array $arguments) { // Stores the original GD resource. $original_res = $this->getToolkit()->getResource(); + // Get expected width and height resulting from the rotation. + $rect = new Rectangle($this->getToolkit()->getWidth(), $this->getToolkit()->getHeight()); + $rect = $rect->rotate($arguments['degrees']); + $expected_width = $rect->getBoundingWidth(); + $expected_height = $rect->getBoundingHeight(); + + // Rotate the image. if ($new_res = imagerotate($this->getToolkit()->getResource(), 360 - $arguments['degrees'], $arguments['background_idx'])) { $this->getToolkit()->setResource($new_res); imagedestroy($original_res); @@ -108,7 +116,22 @@ protected function execute(array $arguments) { imagecolortransparent($this->getToolkit()->getResource(), $transparent_idx); } - return TRUE; + // Resizes the image if width and height are not as expected. + // PHP 7.0.? and 7.1.? GD rotates differently then it did in PHP 5.5 and + // above, resulting in different dimensions. Here we are harmonizing + // final size across PHP versions by resizing the image to the dimensions + // we expect. + // @see https://bugs.php.net/bug.php?id=65148 + // @todo instead of just resizing, crop/canvas the rotated image + $success = TRUE; + if ($this->getToolkit()->getWidth() != $expected_width || $this->getToolkit()->getHeight() != $expected_height) { + $success = $this->getToolkit()->apply('resize', [ + 'width' => $expected_width, + 'height' => $expected_height + ]); + } + + return $success; } return FALSE;