diff --git a/core/modules/image/src/Plugin/ImageEffect/RotateImageEffect.php b/core/modules/image/src/Plugin/ImageEffect/RotateImageEffect.php
index 3b79e43..c516dfe 100644
--- a/core/modules/image/src/Plugin/ImageEffect/RotateImageEffect.php
+++ b/core/modules/image/src/Plugin/ImageEffect/RotateImageEffect.php
@@ -28,12 +28,9 @@ class RotateImageEffect extends ConfigurableImageEffectBase {
* {@inheritdoc}
*/
public function applyEffect(ImageInterface $image) {
- if (!empty($this->configuration['random'])) {
- $degrees = abs((float) $this->configuration['degrees']);
- $this->configuration['degrees'] = rand(-$degrees, $degrees);
- }
+ $degrees = $this->configuration['random'] ? $this->getRotationFromUri($image->getSource(), $this->configuration['degrees']) : $this->configuration['degrees'];
- if (!$image->rotate($this->configuration['degrees'], $this->configuration['bgcolor'])) {
+ if (!$image->rotate($degrees, $this->configuration['bgcolor'])) {
$this->logger->error('Image rotate failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', array('%toolkit' => $image->getToolkitId(), '%path' => $image->getSource(), '%mimetype' => $image->getMimeType(), '%dimensions' => $image->getWidth() . 'x' . $image->getHeight()));
return FALSE;
}
@@ -44,11 +41,12 @@ public function applyEffect(ImageInterface $image) {
* {@inheritdoc}
*/
public function transformDimensions(array &$dimensions, $uri) {
- // If the rotate is not random and current dimensions are set,
- // then the new dimensions can be determined.
- if (!$this->configuration['random'] && $dimensions['width'] && $dimensions['height']) {
+ // If the current dimensions are set, then the new dimensions can be
+ // determined.
+ if ($dimensions['width'] && $dimensions['height']) {
+ $degrees = $this->configuration['random'] ? $this->getRotationFromUri($uri, $this->configuration['degrees']) : $this->configuration['degrees'];
$rect = new Rectangle($dimensions['width'], $dimensions['height']);
- $rect = $rect->rotate($this->configuration['degrees']);
+ $rect = $rect->rotate($degrees);
$dimensions['width'] = $rect->getBoundingWidth();
$dimensions['height'] = $rect->getBoundingHeight();
}
@@ -58,6 +56,27 @@ public function transformDimensions(array &$dimensions, $uri) {
}
/**
+ * Returns a pseudo-random angle for rotation.
+ *
+ * Uses a CRC32B hash of the URI to calculate the pseudo-random angle.
+ *
+ * @param string $uri
+ * The URI of the original file.
+ * @param int $max_degrees
+ * The maximum rotation angle.
+ *
+ * @return int
+ * An integer angle in the range 0-360.
+ */
+ protected function getRotationFromUri($uri, $max_degrees) {
+ if (!$max_degrees || $max_degrees === 0) {
+ return 0;
+ }
+ $max_degrees = abs((int) $max_degrees);
+ return (((int) hash('crc32b', $uri)) % ($max_degrees * 2)) - $max_degrees;
+ }
+
+ /**
* {@inheritdoc}
*/
public function getSummary() {
diff --git a/core/modules/image/src/Tests/ImageDimensionsTest.php b/core/modules/image/src/Tests/ImageDimensionsTest.php
index 6d2fa7d..f7f53b8 100644
--- a/core/modules/image/src/Tests/ImageDimensionsTest.php
+++ b/core/modules/image/src/Tests/ImageDimensionsTest.php
@@ -164,7 +164,7 @@ function testImageDimensions() {
$effect = array(
'id' => 'image_rotate',
'data' => array(
- 'degrees' => 180,
+ 'degrees' => -37,
'random' => TRUE,
),
'weight' => 5,
@@ -172,11 +172,14 @@ function testImageDimensions() {
$style->addImageEffect($effect);
$style->save();
- $this->assertEqual($this->getImageTag($variables), '');
+ $this->assertEqual($this->getImageTag($variables), '');
$this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.');
$this->drupalGet($url);
$this->assertResponse(200, 'Image was generated at the URL.');
$this->assertTrue(file_exists($generated_uri), 'Generated file does exist after we accessed it.');
+ $image_file = $image_factory->get($generated_uri);
+ $this->assertEqual($image_file->getWidth(), 80);
+ $this->assertEqual($image_file->getHeight(), 100);
// Add a crop effect.