Skip to content
This repository has been archived by the owner on Jan 5, 2018. It is now read-only.

Commit

Permalink
Issue #2856573 by mondrake: Integration with File Metadata Manager mo…
Browse files Browse the repository at this point in the history
…dule
  • Loading branch information
mondrake authored and mondrake committed Apr 18, 2017
1 parent 96b5969 commit 30952a6
Show file tree
Hide file tree
Showing 14 changed files with 195 additions and 242 deletions.
10 changes: 10 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "drupal/image_effects",
"type": "drupal-module",
"description": "Provides effects and operations for the Image API.",
"require": {
"drupal/core": ">=8.2.0",
"drupal/file_mdm_exif": "^1",
"drupal/file_mdm_font": "^1"
}
}
2 changes: 2 additions & 0 deletions image_effects.info.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ configure: image_effects.settings
dependencies:
- drupal:image
- drupal:system (>=8.2.0)
- file_mdm:file_mdm_exif
- file_mdm:file_mdm_font
test_dependencies:
- imagemagick:imagemagick
- jquery_colorpicker:jquery_colorpicker
19 changes: 0 additions & 19 deletions image_effects.install
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,6 @@
function image_effects_requirements($phase) {
$requirements = [];

// Check PHP EXIF extension for the auto_rotate image effect.
$requirements['image_effects_exif_extension'] = [
'title' => t('PHP EXIF extension'),
];
if (!extension_loaded('exif')) {
$requirements['image_effects_exif_extension'] += [
'value' => t('Not installed'),
'description' => t('The PHP EXIF extension is not installed. Automatic image orientation effects will not be available with the GD image toolkit.'),
'severity' => REQUIREMENT_WARNING,
];
}
else {
$requirements['image_effects_exif_extension'] += [
'value' => t('Enabled'),
'severity' => REQUIREMENT_INFO,
];

}

// Check PHP GD2 FreeType support.
if (function_exists('gd_info')) {
$info = gd_info();
Expand Down
61 changes: 17 additions & 44 deletions src/Plugin/ImageEffect/AutoOrientImageEffect.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@
namespace Drupal\image_effects\Plugin\ImageEffect;

use Drupal\Core\Image\ImageInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\image\ConfigurableImageEffectBase;
use Drupal\file_mdm\FileMetadataManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface;

/**
* Automatically adjusts the orientation of an image resource.
Expand All @@ -30,18 +29,11 @@
class AutoOrientImageEffect extends ConfigurableImageEffectBase implements ContainerFactoryPluginInterface {

/**
* The MIME type guessing service.
* The file metadata manager service.
*
* @var \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface
* @var \Drupal\file_mdm\FileMetadataManagerInterface
*/
protected $mimeTypeGuesser;

/**
* The file system service.
*
* @var \Drupal\Core\File\FileSystemInterface
*/
protected $fileSystem;
protected $fileMetadataManager;

/**
* Constructs an AutoOrientImageEffect object.
Expand All @@ -54,15 +46,12 @@ class AutoOrientImageEffect extends ConfigurableImageEffectBase implements Conta
* The plugin implementation definition.
* @param \Psr\Log\LoggerInterface $logger
* A logger instance.
* @param \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface $mime_type_guesser
* The MIME type guessing service.
* @param \Drupal\Core\File\FileSystemInterface $file_system
* The file system service.
* @param \Drupal\file_mdm\FileMetadataManagerInterface $file_metadata_manager
* The file metadata manager service.
*/
public function __construct(array $configuration, $plugin_id, array $plugin_definition, LoggerInterface $logger, MimeTypeGuesserInterface $mime_type_guesser, FileSystemInterface $file_system) {
public function __construct(array $configuration, $plugin_id, array $plugin_definition, LoggerInterface $logger, FileMetadataManagerInterface $file_metadata_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $logger);
$this->mimeTypeGuesser = $mime_type_guesser;
$this->fileSystem = $file_system;
$this->fileMetadataManager = $file_metadata_manager;
}

/**
Expand All @@ -74,8 +63,7 @@ public static function create(ContainerInterface $container, array $configuratio
$plugin_id,
$plugin_definition,
$container->get('logger.factory')->get('image'),
$container->get('file.mime_type.guesser'),
$container->get('file_system')
$container->get('file_metadata_manager')
);
}

Expand All @@ -92,11 +80,6 @@ public function defaultConfiguration() {
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
if (!extension_loaded('exif')) {
// Issue a warning if the PHP EXIF extension is not enabled.
drupal_set_message($this->t('This image effect requires the PHP EXIF extension to be enabled to work properly.'), 'warning');
}

$form['info'] = [
'#type' => 'details',
'#title' => $this->t('Information'),
Expand Down Expand Up @@ -161,30 +144,20 @@ public function applyEffect(ImageInterface $image) {
* {@inheritdoc}
*/
public function transformDimensions(array &$dimensions, $uri) {
// Test to see if EXIF is supported by the image format.
$mime_type = $this->mimeTypeGuesser->guess($uri);
if (!in_array($mime_type, ['image/jpeg', 'image/tiff'])) {
// Not an EXIF enabled image, return.
return;
}
if ($dimensions['width'] && $dimensions['height'] && $this->configuration['scan_exif']) {
// Both dimensions in input, and effect is configured to check the
// the input file. Read EXIF data, and determine image orientation.
if (($file_path = $this->fileSystem->realpath($uri)) && function_exists('exif_read_data')) {
if ($exif_data = @exif_read_data($file_path)) {
$orientation = isset($exif_data['Orientation']) ? $exif_data['Orientation'] : NULL;
if (in_array($orientation, [5, 6, 7, 8])) {
$tmp = $dimensions['width'];
$dimensions['width'] = $dimensions['height'];
$dimensions['height'] = $tmp;
}
return;
}
$file = $this->fileMetadataManager->uri($uri);
$orientation = $file->getMetadata('exif', 'Orientation')['value'];
if (in_array($orientation, [5, 6, 7, 8])) {
$tmp = $dimensions['width'];
$dimensions['width'] = $dimensions['height'];
$dimensions['height'] = $tmp;
}
return;
}
// Either no full dimensions in input, or effect is configured to skip
// checking the input file, or EXIF extension is missing. Set both
// dimensions to NULL.
// checking the input file. Set both dimensions to NULL.
$dimensions['width'] = $dimensions['height'] = NULL;
}

Expand Down
82 changes: 30 additions & 52 deletions src/Plugin/ImageToolkit/Operation/FontOperationTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,17 @@

namespace Drupal\image_effects\Plugin\ImageToolkit\Operation;

use Drupal\Core\StreamWrapper\LocalStream;

/**
* Base trait for image toolkit operations that require font handling.
*/
trait FontOperationTrait {

/**
* The stream wrapper manager service.
*
* @var \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface
*/
protected $streamWrapperManagerForFontHandling;

/**
* An array of resolved font file URIs.
*
* @var array
*/
protected static $fontPaths = [];

/**
* Return the real path of the specified file.
*
* @param string $uri
* An URI.
*
* @return string
* The local path of the file.
*/
protected function getRealFontPath($uri) {
$uri_wrapper = $this->getStreamWrapperManagerForFontHandling()->getViaUri($uri);
if ($uri_wrapper instanceof LocalStream) {
return $uri_wrapper->realpath();
}
else {
return is_file($uri) ? $uri : NULL;
}
}

/**
* Return the path of the font file.
*
* The imagettf* GD functions, and ImageMagick toolkit, do not allow use of
* URIs to specify files. Always resolve the font file to a local path.
*
* @param string $font_uri
* The font URI.
*
Expand All @@ -55,26 +23,36 @@ protected function getFontPath($font_uri) {
if (!$font_uri) {
throw new \InvalidArgumentException('Font file not specified');
}
if (!isset(static::$fontPaths[$font_uri])) {
if (!$ret = $this->getRealFontPath($font_uri)) {
throw new \InvalidArgumentException("Could not find the font file {$font_uri}");
}
static::$fontPaths[$font_uri] = $ret;

// Determine if the $font_uri is a real URI or a local path.
$uri_wrapper = \Drupal::service('stream_wrapper_manager')->getViaUri($font_uri);

// If local path, return it.
if ($uri_wrapper === FALSE) {
return $font_uri;
}
return static::$fontPaths[$font_uri];
}

/**
* Returns the stream wrapper manager service.
*
* @return \Drupal\Core\StreamWrapper\streamWrapperManagerInterface
* The stream wrapper manager service.
*/
protected function getStreamWrapperManagerForFontHandling() {
if (!$this->streamWrapperManagerForFontHandling) {
$this->streamWrapperManagerForFontHandling = \Drupal::service('stream_wrapper_manager');
// Determine if a local path can be resolved for the URI. If so, return it.
$local_path = $uri_wrapper->realpath();
if ($local_path !== FALSE) {
return $local_path;
}
return $this->streamWrapperManagerForFontHandling;

// If no local path available, the file may be stored in a remote file
// system. Use the file metadata manager service to copy the file to local
// temp and keep it there for further access within same request. It is not
// necessary to load its metadata.
$file = \Drupal::service('file_metadata_manager')->uri($font_uri);
$local_path = $file->getLocalTempPath();
if ($local_path !== NULL) {
return $local_path;
}
elseif ($file->copyUriToTemp() === TRUE) {
return $file->getLocalTempPath();
}

// None of the above worked, file can not be accessed.
throw new \InvalidArgumentException("Cannot access font file '$font_uri'");
}

}
13 changes: 4 additions & 9 deletions src/Plugin/ImageToolkit/Operation/gd/AutoOrient.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,10 @@ protected function execute(array $arguments) {
return TRUE;
}

// Will not work without EXIF extension installed.
if (!function_exists('exif_read_data')) {
$this->logger->notice('The image %file could not be auto-rotated because the exif_read_data() function is not available in this PHP installation. Check if the PHP EXIF extension is enabled.', ['%file' => $this->getToolkit()->getSource()]);
return FALSE;
}

// Read EXIF data.
$exif = @exif_read_data(\Drupal::service('file_system')->realpath($source_path));
if (isset($exif['Orientation'])) {
$file = \Drupal::service('file_metadata_manager')->uri($source_path);
$orientation = $file->getMetadata('exif', 'Orientation')['value'];
if ($orientation !== NULL) {
// http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html:
// 1 = Horizontal (normal) [top-left].
// 2 = Mirror horizontal [top-right].
Expand All @@ -52,7 +47,7 @@ protected function execute(array $arguments) {
// 6 = Rotate 90 CW [right-top].
// 7 = Mirror horizontal and rotate 90 CW [right-bottom].
// 8 = Rotate 270 CW [left-bottom].
switch ($exif['Orientation']) {
switch ($orientation) {
case 2:
return $this->getToolkit()->apply('mirror', ['x_axis' => TRUE]);

Expand Down
Loading

0 comments on commit 30952a6

Please sign in to comment.