From 87b377b440bb8cb903d74eef22a07d154119e5e5 Mon Sep 17 00:00:00 2001 From: Daniel Berthereau Date: Mon, 29 Oct 2018 00:00:00 +0100 Subject: [PATCH] Added controller plugin and view helper imageSize(). --- config/module.config.php | 4 + config/module.ini | 6 +- data/scripts/upgrade.php | 6 +- src/Controller/ImageController.php | 84 +------------ src/Mvc/Controller/Plugin/ImageSize.php | 119 ++++++++++++++++++ .../ControllerPlugin/ImageSizeFactory.php | 16 +++ src/Service/ViewHelper/ImageSizeFactory.php | 18 +++ src/View/Helper/IiifInfo.php | 89 +------------ src/View/Helper/IiifManifest.php | 107 +++++----------- src/View/Helper/ImageSize.php | 45 +++++++ 10 files changed, 245 insertions(+), 249 deletions(-) create mode 100644 src/Mvc/Controller/Plugin/ImageSize.php create mode 100644 src/Service/ControllerPlugin/ImageSizeFactory.php create mode 100644 src/Service/ViewHelper/ImageSizeFactory.php create mode 100644 src/View/Helper/ImageSize.php diff --git a/config/module.config.php b/config/module.config.php index 3064172..011b358 100644 --- a/config/module.config.php +++ b/config/module.config.php @@ -20,6 +20,7 @@ 'factories' => [ 'iiifInfo' => Service\ViewHelper\IiifInfoFactory::class, 'iiifManifest' => Service\ViewHelper\IiifManifestFactory::class, + 'imageSize' => Service\ViewHelper\ImageSizeFactory::class, ], ], 'form_elements' => [ @@ -43,6 +44,9 @@ 'tileInfo' => Mvc\Controller\Plugin\TileInfo::class, 'tileServer' => Mvc\Controller\Plugin\TileServer::class, ], + 'factories' => [ + 'imageSize' => Service\ControllerPlugin\ImageSizeFactory::class, + ], ], 'media_ingesters' => [ 'factories' => [ diff --git a/config/module.ini b/config/module.ini index e61cd89..d31fd45 100644 --- a/config/module.ini +++ b/config/module.ini @@ -1,12 +1,12 @@ [info] name = "IIIF Server" description = "Integrates the IIIF specifications and a simple IIP Image Server to allow to process and share instantly images of any size and medias (pdf, audio, video, 3D...) in the desired formats." -tags = "specification, standard, share" +tags = "iiif, image server, specification, standard, share" license = "CeCILL v2.1" author = "Daniel Berthereau, Omeka S port by BibLibre" author_link = "https://github.com/Daniel-KM" module_link = "https://github.com/Daniel-KM/Omeka-S-module-IiifServer" support_link = "https://github.com/Daniel-KM/Omeka-S-module-IiifServer/issues" configurable = true -version = "3.5.10" -omeka_version_constraint = "^1.0.0" +version = "3.5.11" +omeka_version_constraint = "^1.1.0" diff --git a/data/scripts/upgrade.php b/data/scripts/upgrade.php index fbee6d2..fbcc81f 100644 --- a/data/scripts/upgrade.php +++ b/data/scripts/upgrade.php @@ -1,7 +1,5 @@ translate('This version requires Archive Repertory 3.15.4 or greater (used for some 3D views).')); // @translate } } diff --git a/src/Controller/ImageController.php b/src/Controller/ImageController.php index 2490509..4597ce8 100644 --- a/src/Controller/ImageController.php +++ b/src/Controller/ImageController.php @@ -362,7 +362,8 @@ protected function _cleanRequest(MediaRepresentation $media) $transform['source']['filepath'] = $this->_getImagePath($media, 'original'); $transform['source']['media_type'] = $media->mediaType(); - list($sourceWidth, $sourceHeight) = array_values($this->_getImageSize($media, 'original')); + $imageSize = $this->imageSize($media, 'original'); + list($sourceWidth, $sourceHeight) = $imageSize ? array_values($imageSize) : [null, null]; $transform['source']['width'] = $sourceWidth; $transform['source']['height'] = $sourceHeight; @@ -515,7 +516,8 @@ protected function _cleanRequest(MediaRepresentation $media) foreach ($availableTypes as $imageType) { $filepath = $this->_getImagePath($media, $imageType); if ($filepath) { - list($testWidth, $testHeight) = array_values($this->_getImageSize($media, $imageType)); + $imageSize = $this->imageSize($media, $imageType); + list($testWidth, $testHeight) = $imageSize ? array_values($imageSize) : [null, null]; if ($destinationWidth == $testWidth && $destinationHeight == $testHeight) { $transform['size']['feature'] = 'full'; // Change the source file to avoid a transformation. @@ -649,7 +651,8 @@ protected function _useOmekaDerivative(MediaRepresentation $media, $transform) // Currently, the check is done only on fullsize. $derivativeType = 'large'; - list($derivativeWidth, $derivativeHeight) = array_values($this->_getImageSize($media, $derivativeType)); + $imageSize = $this->imageSize($media, $derivativeType); + list($derivativeWidth, $derivativeHeight) = $imageSize ? array_values($imageSize) : [null, null]; switch ($transform['size']['feature']) { case 'sizeByW': case 'sizeByH': @@ -737,39 +740,6 @@ protected function _transformImage($args) return $imageServer->transform($args); } - /** - * Get an array of the width and height of the image file. - * - * @param MediaRepresentation $media - * @param string $imageType - * @return array Associative array of width and height of the image file. - * If the file is not an image, the width and the height will be null. - * - * @see \IiifServer\View\Helper\IiifManifest::_getImageSize() - * @see \IiifServer\View\Helper\IiifInfo::_getImageSize() - * @todo Refactorize. - */ - protected function _getImageSize(MediaRepresentation $media, $imageType = 'original') - { - // Check if this is an image. - if (empty($media) || strpos($media->mediaType(), 'image/') !== 0) { - return [ - 'width' => null, - 'height' => null, - ]; - } - - $filepath = $this->_mediaFilePath($media, $imageType); - - $result = $this->_getWidthAndHeight($filepath); - - if (empty($result['width']) || empty($result['height'])) { - throw new Exception("Failed to get image resolution: $filepath"); - } - - return $result; - } - /** * Get the path to an original or derivative file for an image. * @@ -810,46 +780,4 @@ protected function getStoragePath($prefix, $name, $extension = null) { return sprintf('%s/%s%s', $prefix, $name, $extension ? ".$extension" : null); } - - /** - * Helper to get width and height of an image. - * - * @param string $filepath This should be an image (no check here). - * @return array Associative array of width and height of the image file. - * If the file is not an image, the width and the height will be null. - * @see \IiifServer\View\Helper\IiifInfo::_getWidthAndHeight() - * @todo Refactorize. - */ - protected function _getWidthAndHeight($filepath) - { - // An internet path. - if (strpos($filepath, 'https://') === 0 || strpos($filepath, 'http://') === 0) { - $tempFile = $this->tempFileFactory->build(); - $tempPath = $tempFile->getTempPath(); - $tempFile->delete(); - $result = file_put_contents($tempPath, $filepath); - if ($result !== false) { - list($width, $height) = getimagesize($tempPath); - unlink($tempPath); - return [ - 'width' => $width, - 'height' => $height, - ]; - } - unlink($tempPath); - } - // A normal path. - elseif (file_exists($filepath)) { - list($width, $height) = getimagesize($filepath); - return [ - 'width' => $width, - 'height' => $height, - ]; - } - - return [ - 'width' => null, - 'height' => null, - ]; - } } diff --git a/src/Mvc/Controller/Plugin/ImageSize.php b/src/Mvc/Controller/Plugin/ImageSize.php new file mode 100644 index 0000000..d944619 --- /dev/null +++ b/src/Mvc/Controller/Plugin/ImageSize.php @@ -0,0 +1,119 @@ +basePath = $basePath; + $this->tempFileFactory = $tempFileFactory; + } + + /** + * Get an array of the width and height of the image file from a media. + * + * @todo Store size in the data of the media. + * + * @param MediaRepresentation $media + * @param string $imageType + * @throws RuntimeException + * @return array|null Associative array of width and height of the image + * file, else null. + */ + public function __invoke(MediaRepresentation $media, $imageType = 'original') + { + // Check if this is an image. + if (strtok($media->mediaType(), '/') !== 'image') { + return null; + } + + // The storage adapter should be checked for external storage. + $storagePath = $imageType == 'original' + ? $this->getStoragePath($imageType, $media->filename()) + : $this->getStoragePath($imageType, $media->storageId(), 'jpg'); + $filepath = $this->basePath . DIRECTORY_SEPARATOR . $storagePath; + $result = $this->getWidthAndHeight($filepath); + + // This is an image, but failed to get the resolution. + if (empty($result)) { + throw new RuntimeException(new Message('Failed to get image resolution: %s', // @translate + $storagePath)); + } + + return $result; + } + + /** + * Get a storage path. + * + * @param string $prefix The storage prefix + * @param string $name The file name, or basename if extension is passed + * @param null|string $extension The file extension + * @return string + */ + protected function getStoragePath($prefix, $name, $extension = '') + { + return sprintf('%s/%s%s', $prefix, $name, strlen($extension) ? '.' . $extension : ''); + } + + /** + * Helper to get width and height of an image. + * + * @param string $filepath This should be an image (no check here). + * @return array|null Associative array of width and height of the image + * file, else null. + */ + protected function getWidthAndHeight($filepath) + { + // An internet path. + if (strpos($filepath, 'https://') === 0 || strpos($filepath, 'http://') === 0) { + $tempFile = $this->tempFileFactory->build(); + $tempPath = $tempFile->getTempPath(); + $tempFile->delete(); + $result = file_put_contents($tempPath, $filepath); + if ($result !== false) { + $result = getimagesize($tempPath); + if ($result) { + list($width, $height) = $result; + } + } + unlink($tempPath); + } + // A normal path. + elseif (file_exists($filepath)) { + $result = getimagesize($filepath); + if ($result) { + list($width, $height) = $result; + } + } + + if (empty($width) || empty($height)) { + return null; + } + + return [ + 'width' => $width, + 'height' => $height, + ]; + } +} diff --git a/src/Service/ControllerPlugin/ImageSizeFactory.php b/src/Service/ControllerPlugin/ImageSizeFactory.php new file mode 100644 index 0000000..70340a4 --- /dev/null +++ b/src/Service/ControllerPlugin/ImageSizeFactory.php @@ -0,0 +1,16 @@ +get('Config')['file_store']['local']['base_path'] ?: (OMEKA_PATH . '/files'); + $tempFileFactory = $services->get('Omeka\File\TempFileFactory'); + return new ImageSize($basePath, $tempFileFactory); + } +} diff --git a/src/Service/ViewHelper/ImageSizeFactory.php b/src/Service/ViewHelper/ImageSizeFactory.php new file mode 100644 index 0000000..c2d8198 --- /dev/null +++ b/src/Service/ViewHelper/ImageSizeFactory.php @@ -0,0 +1,18 @@ +get('ControllerPluginManager'); + $plugin = $pluginManager->get('imageSize'); + return new ImageSize( + $plugin + ); + } +} diff --git a/src/View/Helper/IiifInfo.php b/src/View/Helper/IiifInfo.php index 4101e60..6512f67 100644 --- a/src/View/Helper/IiifInfo.php +++ b/src/View/Helper/IiifInfo.php @@ -69,10 +69,11 @@ public function __construct(TempFileFactory $tempFileFactory, $basePath) public function __invoke(MediaRepresentation $media) { if (strpos($media->mediaType(), 'image/') === 0) { + $view = $this->getView(); $sizes = []; $availableTypes = ['medium', 'large', 'original']; foreach ($availableTypes as $imageType) { - $imageSize = $this->_getImageSize($media, $imageType); + $imageSize = $view->imageSize($media, $imageType) ?: ['width' => null, 'height' => null]; $size = []; $size['width'] = $imageSize['width']; $size['height'] = $imageSize['height']; @@ -81,8 +82,8 @@ public function __invoke(MediaRepresentation $media) } $imageType = 'original'; - $imageSize = $this->_getImageSize($media, $imageType); - list($width, $height) = array_values($imageSize); + $imageSize = $view->imageSize($media, $imageType); + list($width, $height) = $imageSize ? array_values($imageSize) : [null, null]; $imageUrl = $this->view->url( 'iiifserver_image', ['id' => $media->id()], @@ -206,86 +207,4 @@ protected function getStoragePath($prefix, $name, $extension = null) { return sprintf('%s/%s%s', $prefix, $name, $extension ? ".$extension" : null); } - - /** - * Get an array of the width and height of the image file. - * - * @param MediaRepresentation $media - * @param string $imageType - * @return array Associative array of width and height of the image file. - * If the file is not an image, the width and the height will be null. - * - * @see \IiifServer\View\Helper\IiifManifest::_getImageSize() - * @see \IiifServer\View\Helper\IiifInfo::_getImageSize() - * @see \IiifServer\Controller\ImageController::_getImageSize() - * @todo Refactorize. - */ - protected function _getImageSize(MediaRepresentation $media, $imageType = 'original') - { - // Check if this is an image. - if (empty($media) || strpos($media->mediaType(), 'image/') !== 0) { - return [ - 'width' => null, - 'height' => null, - ]; - } - - // The storage adapter should be checked for external storage. - if ($imageType == 'original') { - $storagePath = $this->getStoragePath($imageType, $media->filename()); - } else { - $storagePath = $this->getStoragePath($imageType, $media->storageId(), 'jpg'); - } - $filepath = $this->basePath - . DIRECTORY_SEPARATOR . $storagePath; - $result = $this->_getWidthAndHeight($filepath); - - if (empty($result['width']) || empty($result['height'])) { - throw new \Exception("Failed to get image resolution: $filepath"); - } - - return $result; - } - - /** - * Helper to get width and height of an image. - * - * @param string $filepath This should be an image (no check here). - * @return array Associative array of width and height of the image file. - * If the file is not an image, the width and the height will be null. - * @see \IiifServer\Controller\ImageController::_getWidthAndHeight() - * @todo Refactorize. - */ - protected function _getWidthAndHeight($filepath) - { - // An internet path. - if (strpos($filepath, 'https://') === 0 || strpos($filepath, 'http://') === 0) { - $tempFile = $this->tempFileFactory->build(); - $tempPath = $tempFile->getTempPath(); - $tempFile->delete(); - $result = file_put_contents($tempPath, $filepath); - if ($result !== false) { - list($width, $height) = getimagesize($tempPath); - unlink($tempPath); - return [ - 'width' => $width, - 'height' => $height, - ]; - } - unlink($tempPath); - } - // A normal path. - elseif (file_exists($filepath)) { - list($width, $height) = getimagesize($filepath); - return [ - 'width' => $width, - 'height' => $height, - ]; - } - - return [ - 'width' => null, - 'height' => null, - ]; - } } diff --git a/src/View/Helper/IiifManifest.php b/src/View/Helper/IiifManifest.php index 063ace9..3436427 100644 --- a/src/View/Helper/IiifManifest.php +++ b/src/View/Helper/IiifManifest.php @@ -30,7 +30,6 @@ namespace IiifServer\View\Helper; -use Exception; use IiifServer\Mvc\Controller\Plugin\TileInfo; use Omeka\Api\Representation\AbstractResourceEntityRepresentation; use Omeka\Api\Representation\ItemRepresentation; @@ -468,11 +467,11 @@ protected function buildManifestItem(ItemRepresentation $item) */ protected function _iiifThumbnail(MediaRepresentation $media) { - $imageSize = $this->_getImageSize($media, 'square'); - list($width, $height) = array_values($imageSize); - if (empty($width) || empty($height)) { + $imageSize = $this->getView()->imageSize($media, 'square'); + if (empty($imageSize)) { return; } + list($width, $height) = array_values($imageSize); $thumbnail = []; @@ -521,13 +520,10 @@ protected function _iiifThumbnail(MediaRepresentation $media) */ protected function _iiifImage(MediaRepresentation $media, $index, $canvasUrl, $width = null, $height = null) { - if (empty($media)) { - return; - } - + $view = $this->getView(); if (empty($width) || empty($height)) { - $sizeFile = $this->_getImageSize($media, 'original'); - list($width, $height) = array_values($sizeFile); + $imageSize = $view->imageSize($media, 'original'); + list($width, $height) = $imageSize ? array_values($imageSize) : [null, null]; } $image = []; @@ -545,8 +541,8 @@ protected function _iiifImage(MediaRepresentation $media, $index, $canvasUrl, $w // This is a tiled image. if ($iiifTileInfo) { - $largeSize = $this->_getImageSize($media, 'large'); - list($widthLarge, $heightLarge) = array_values($largeSize); + $imageSize = $view->imageSize($media, 'large'); + list($widthLarge, $heightLarge) = $imageSize ? array_values($imageSize) : [null, null]; $imageUrl = $this->view->url( 'iiifserver_image', [ @@ -646,7 +642,8 @@ protected function _iiifCanvasImage(MediaRepresentation $media, $index) // Size of canvas should be the double of small images (< 1200 px), but // only when more than image is used by a canvas. - list($width, $height) = array_values($this->_getImageSize($media, 'original')); + $imageSize = $this->getView()->imageSize($media, 'original'); + list($width, $height) = $imageSize ? array_values($imageSize) : [null, null]; $canvas['width'] = $width; $canvas['height'] = $height; @@ -678,7 +675,7 @@ protected function _iiifCanvasPlaceholder() $placeholder = 'img/thumbnails/placeholder-image.png'; $canvas['thumbnail'] = $this->view->assetUrl($placeholder, 'IiifServer'); - $imageSize = $this->_getWidthAndHeight(OMEKA_PATH . '/modules/IiifServer/asset/' . $placeholder); + $imageSize = $this->getWidthAndHeight(OMEKA_PATH . '/modules/IiifServer/asset/' . $placeholder) ?: ['width' => null, 'height' => null]; $canvas['width'] = $imageSize['width']; $canvas['height'] = $imageSize['height']; @@ -1053,63 +1050,14 @@ protected function getStoragePath($prefix, $name, $extension = null) return sprintf('%s/%s%s', $prefix, $name, $extension ? ".$extension" : null); } - /** - * Get an array of the width and height of the image file. - * - * @param MediaRepresentation $media - * @param string $imageType - * @return array Associative array of width and height of the image file. - * If the file is not an image, the width and the height will be null. - * - * @see IiifInfo::_getImageSize() - * @see \IiifServer\Controller\ImageController::_getImageSize() - * @todo Refactorize. - */ - protected function _getImageSize(MediaRepresentation $media, $imageType = 'original') - { - // Check if this is an image. - if (empty($media)) { - return [ - 'width' => null, - 'height' => null, - ]; - } - - $mediaType = $media->mediaType(); - if (empty($mediaType) || strpos($mediaType, 'image/') !== 0) { - return [ - 'width' => null, - 'height' => null, - ]; - } - - // The storage adapter should be checked for external storage. - if ($imageType == 'original') { - $storagePath = $this->getStoragePath($imageType, $media->filename()); - } else { - $storagePath = $this->getStoragePath($imageType, $media->storageId(), 'jpg'); - } - $filepath = $this->basePath - . DIRECTORY_SEPARATOR . $storagePath; - $result = $this->_getWidthAndHeight($filepath); - - if (empty($result['width']) || empty($result['height'])) { - throw new Exception("Failed to get image resolution: $filepath"); - } - - return $result; - } - /** * Helper to get width and height of an image. * * @param string $filepath This should be an image (no check here). - * @return array Associative array of width and height of the image file. - * If the file is not an image, the width and the height will be null. - * @see \IiifServer\Controller\ImageController::_getWidthAndHeight() - * @todo Refactorize. + * @return array|null Associative array of width and height of the image + * file, else null. */ - protected function _getWidthAndHeight($filepath) + protected function getWidthAndHeight($filepath) { // An internet path. if (strpos($filepath, 'https://') === 0 || strpos($filepath, 'http://') === 0) { @@ -1118,27 +1066,28 @@ protected function _getWidthAndHeight($filepath) $tempFile->delete(); $result = file_put_contents($tempPath, $filepath); if ($result !== false) { - list($width, $height) = getimagesize($tempPath); - unlink($tempPath); - return [ - 'width' => $width, - 'height' => $height, - ]; + $result = getimagesize($tempPath); + if ($result) { + list($width, $height) = $result; + } } unlink($tempPath); } // A normal path. elseif (file_exists($filepath)) { - list($width, $height) = getimagesize($filepath); - return [ - 'width' => $width, - 'height' => $height, - ]; + $result = getimagesize($filepath); + if ($result) { + list($width, $height) = $result; + } + } + + if (empty($width) || empty($height)) { + return null; } return [ - 'width' => null, - 'height' => null, + 'width' => $width, + 'height' => $height, ]; } } diff --git a/src/View/Helper/ImageSize.php b/src/View/Helper/ImageSize.php new file mode 100644 index 0000000..3e05b82 --- /dev/null +++ b/src/View/Helper/ImageSize.php @@ -0,0 +1,45 @@ +imageSizePlugin = $imageSizePlugin; + } + + /** + * Get an array of the width and height of the image file from a media. + * + * @todo Store size in the data of the media. + * + * @param MediaRepresentation $media + * @param string $imageType + * @throws RuntimeException + * @return array|null Associative array of width and height of the image + * file, else null. + */ + public function __invoke(MediaRepresentation $media, $imageType = 'original') + { + $imageSizePlugin = $this->imageSizePlugin; + try { + return $imageSizePlugin($media, $imageType); + } catch (RuntimeException $e) { + throw new Exception\RuntimeException($e->getMessage()); + } + } +}