Further work on the new resizing functionality
This commit is contained in:
parent
c3fbc130dc
commit
f56d1eebe8
|
|
@ -1,11 +1,57 @@
|
|||
==
|
||||
<?php
|
||||
/**
|
||||
* $width = numeric, 'auto' | false | null
|
||||
* $height = numeric, 'auto' | false | null
|
||||
* $options = null | array [
|
||||
* 'mode' => [
|
||||
* 'auto', // automatically choose between portrait and landscape based on the image's orientation
|
||||
* 'exact', // resize to the exact dimensions given, without preserving aspect ratio
|
||||
* 'portrait', // resize to the given height and adapt the width to preserve aspect ratio
|
||||
* 'landscape', // resize to the given width and adapt the height to preserve aspect ratio
|
||||
* 'crop', // crop to the given dimensions after fitting as much of the image as possible inside those
|
||||
* 'fit', // fit the image inside the given maximal dimensions, keeping the aspect ratio
|
||||
* ],
|
||||
* 'quality' => numeric, 1 - 100
|
||||
* 'interlace' => boolean (default false),
|
||||
* 'extension' => ['auto', 'png', 'gif', 'jpg', 'jpeg', 'webp', 'bmp', 'ico'],
|
||||
* 'offset' => [x, y] Offset to crop the image from
|
||||
* 'sharpen' => numeric, 1 - 100
|
||||
*
|
||||
* // Options that could be processed by an addon
|
||||
*
|
||||
* 'blur' => numeric, 1 - 100
|
||||
* 'brightness'=> numeric, -100 - 100
|
||||
* 'contrast' => numeric, -100 - 100
|
||||
* 'pixelate' => numeric, 1 - 5000
|
||||
* 'greyscale' => boolean
|
||||
* 'invert' => boolean
|
||||
* 'opacity' => numeric, 0 - 100
|
||||
* 'rotate' => numeric, 1 - 360
|
||||
* 'flip' => [h, v]
|
||||
* 'background' | 'fill' => string, hex value
|
||||
* 'colourize' => string, RGB value
|
||||
* ]
|
||||
*
|
||||
* Event::fire('system.resize.afterResize')
|
||||
* Event::fire('system.resize.beforeResize')
|
||||
* Event::fire('system.resize.processResize')
|
||||
*
|
||||
*
|
||||
*
|
||||
|
||||
use App;
|
||||
use Storage;
|
||||
use October\Rain\Database\Attach\File as FileModel;
|
||||
|
||||
/**
|
||||
* DRAFT RESIZER DESIGN
|
||||
* This is a rough draft, very WIP, of what the Image resizer UX / API will look like in October.
|
||||
*
|
||||
* Notes:
|
||||
* - Clearing the application cache should not invalidate any existing resized images
|
||||
* - Invalid images should not result in a valid "image not found" image existing, it should result in a 404 or more specific error
|
||||
* - Provide a new backend list column type "thumb" that will pass it through the resizer
|
||||
*
|
||||
* Configurations to support
|
||||
*
|
||||
|
|
@ -14,6 +60,9 @@
|
|||
* final generated image as requested or a link to the resizer route that will actually handle resizing the image.
|
||||
* - User should be able to extend the image resizing to provide pre or post processing of the images before / after being resized
|
||||
* also to include the ability to swap out the image resizer itself. The core workflow logic should remain the same though.
|
||||
* Examples:
|
||||
* - Post processing of resized images with TinyPNG to optimize filesize further
|
||||
* - Replacement processing of resizing with Intervention Image (using GD or ImageMagick)
|
||||
*/
|
||||
class Helper {
|
||||
/**
|
||||
|
|
@ -31,9 +80,122 @@ class Helper {
|
|||
*/
|
||||
public function getIdentifier($image, $width = null, $height = null, array $options = [])
|
||||
{
|
||||
$image = static::normalizeImage($image);
|
||||
|
||||
if (is_null($image)) {
|
||||
throw new \Exception("Unable to process the provided image: " . var_export($image));
|
||||
}
|
||||
|
||||
$properties = [
|
||||
'image' => $image,
|
||||
'width' => $width,
|
||||
'height' => $height,
|
||||
'options' => $options,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the provided input into information that the resizer can work with
|
||||
*
|
||||
* @param mixed $image Supported values below:
|
||||
* ['disk' => string, 'path' => string],
|
||||
* instance of October\Rain\Database\Attach\File,
|
||||
* string containing URL or path accessible to the application's filesystem manager
|
||||
* @return array|null Array containing the disk and path ['disk' => string, 'path' => string], null if not found
|
||||
*/
|
||||
public static function normalizeImage($image)
|
||||
{
|
||||
$disk = null;
|
||||
$path = null;
|
||||
|
||||
// Process an array
|
||||
if (is_array($image) && !empty($image['disk']) && !empty($image['path'])) {
|
||||
$disk = $image['disk'];
|
||||
$path = $image['path'];
|
||||
|
||||
// Process a FileModel
|
||||
} elseif ($image instanceof FileModel) {
|
||||
$disk = $image->getDisk();
|
||||
$path = $image->getDiskPath();
|
||||
|
||||
// Process a string
|
||||
} elseif (is_string($image)) {
|
||||
// Parse the provided image path into a filesystem ready relative path
|
||||
$relativePath = urldecode(parse_url($image, PHP_URL_PATH));
|
||||
|
||||
// Loop through the sources available to the application to pull from
|
||||
// to identify the source most likely to be holding the image
|
||||
$resizeSources = [
|
||||
'themes' => [
|
||||
'disk' => 'system',
|
||||
'folder' => config('cms.themesPathLocal', base_path('themes')),
|
||||
'path' => config('cms.themesPath', '/themes'),
|
||||
],
|
||||
'plugins' => [
|
||||
'disk' => 'system',
|
||||
'folder' => config('cms.pluginsPathLocal', base_path('plugins')),
|
||||
'path' => config('cms.pluginsPath', '/plugins'),
|
||||
],
|
||||
'media' => [
|
||||
'disk' => config('cms.storage.media.disk', 'local'),
|
||||
'folder' => config('cms.storage.media.folder', 'media'),
|
||||
'path' => config('cms.storage.media.path', '/storage/app/media'),
|
||||
],
|
||||
'modules' => [
|
||||
'disk' => 'system',
|
||||
'folder' => base_path('modules'),
|
||||
'path' => '/modules',
|
||||
],
|
||||
'uploads' => [
|
||||
'disk' => config('cms.storage.uploads.disk', 'local'),
|
||||
'folder' => config('cms.storage.uploads.folder', 'uploads'),
|
||||
'path' => config('cms.storage.uploads.path', '/storage/app/uploads'),
|
||||
],
|
||||
];
|
||||
foreach ($resizeSources as $source => $details) {
|
||||
// Normalize the source path
|
||||
$sourcePath = urldecode(parse_url($details['path'], PHP_URL_PATH));
|
||||
|
||||
// Identify if the current source is a match
|
||||
if (starts_with($relativePath, $sourcePath)) {
|
||||
// Generate a path relative to the selected disk
|
||||
$path = $details['folder'] . '/' . str_after($relativePath, $sourcePath . '/');
|
||||
|
||||
// Handle disks of type "system" (the local file system the application is running on)
|
||||
if ($details['disk'] === 'system') {
|
||||
Config::set('filesystems.disks.system', [
|
||||
'driver' => 'local',
|
||||
'root' => base_path(),
|
||||
]);
|
||||
// Regenerate the path relative to the newly defined "system" disk
|
||||
$path = str_after($path, base_path() . '/');
|
||||
}
|
||||
|
||||
$disk = Storage::disk($details['disk']);
|
||||
|
||||
// Verify that the file exists before exiting the identification process
|
||||
if ($disk->exists($path)) {
|
||||
break;
|
||||
} else {
|
||||
$disk = null;
|
||||
$path = null;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$disk || !$path) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'disk' => $disk,
|
||||
'path' => $path,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the reference to the resized image if the requested resize exists
|
||||
*
|
||||
|
|
|
|||
|
|
@ -325,6 +325,12 @@ return [
|
|||
'path' => '/storage/app/media',
|
||||
],
|
||||
|
||||
'resized' => [
|
||||
'disk' => 'local',
|
||||
'folder' => 'resized',
|
||||
'path' => '/storage/app/resized',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue