[]] + $element['#upload_validators']; } } /** * Ensures that image orientation is according to exif data. * * @param \Drupal\file\FileInterface $file * A file entity. This function may rotate the file. * * @return array * An empty array. * * @see hook_file_validate() */ function exif_orientation_validate_image_rotation(FileInterface $file) { _exif_orientation_rotate($file); // This validator did not produce any errors. return []; } /** * Rotates an image to its EXIF Orientation. * * IPhone 4 and up save all images in landscape, relying on EXIF data to * set the orientation properly. This does not always translate well in the * browser or other devices. * See: http://www.daveperrett.com/articles/2012/07/28/exif-orientation-handling-is-a-ghetto/ * * @param \Drupal\file\FileInterface $file * File entity. */ function _exif_orientation_rotate(FileInterface $file) { $mime_types = ['image/jpeg', 'image/png']; if (function_exists('exif_read_data') && in_array($file->getMimeType(), $mime_types)) { $uri = $file->getFileUri(); // Can't get stream wrapper if URI is without scheme. if (!StreamWrapperManager::getScheme($uri)) { $path = \Drupal::service('file_system')->realpath($uri); } else { /** @var \Drupal\Core\StreamWrapper\StreamWrapperInterface $wrapper */ $wrapper = \Drupal::service('stream_wrapper_manager')->getViaUri($uri); $path = $wrapper->realpath(); if (empty($path)) { $path = $wrapper->getExternalUrl(); } } if (!$path) { return; } $file_exif = @exif_read_data($path); // Ensure that the Orientation key|value exists, otherwise leave. if (!is_array($file_exif) || !isset($file_exif['Orientation'])) { return; } // Orientation numbers and corresponding degrees. // @note: Odd numbers are flipped images, would need different process. switch ($file_exif['Orientation']) { case 3: $degrees = 180; break; case 6: $degrees = 90; break; case 8: $degrees = 270; break; default: $degrees = 0; } if ($degrees > 0) { $image = \Drupal::service('image.factory')->get($file->getFileUri()); if ($image->rotate($degrees)) { $image->save(); } } } }