diff --git a/app/Models/Media.php b/app/Models/Media.php index f34ac16..2d12bf5 100644 --- a/app/Models/Media.php +++ b/app/Models/Media.php @@ -3,12 +3,13 @@ namespace App\Models; use App\Traits\Uuids; -use Illuminate\Contracts\Container\BindingResolutionException; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Http\UploadedFile; use Illuminate\Support\Facades\Storage; +use Intervention\Image\Facades\Image; +use Spatie\ImageOptimizer\OptimizerChainFactory; class Media extends Model { @@ -168,6 +169,31 @@ class Media extends Model } $path = Storage::disk($storage)->path($name); + + // Generate additional image sizes + $sizes = [ + 'thumb' => [150, 150], + 'medium' => [300, 300], + 'large' => [1024, 1024], + ]; + $images = ['full' => $path]; + foreach ($sizes as $sizeName => $size) { + $image = Image::make($path); + $image->resize($size[0], $size[1], function ($constraint) { + $constraint->aspectRatio(); + $constraint->upsize(); + }); + $newPath = pathinfo($path, PATHINFO_DIRNAME) . '/' . pathinfo($path, PATHINFO_FILENAME) . "-$sizeName." . pathinfo($path, PATHINFO_EXTENSION); + $image->save($newPath); + $images[$sizeName] = $newPath; + } + + // Optimize all images + $optimizerChain = OptimizerChainFactory::create(); + foreach ($images as $imagePath) { + $optimizerChain->optimize($imagePath); + } + return [ 'name' => $name, 'path' => $path diff --git a/composer.json b/composer.json index d7dbcd5..1e9d3a0 100644 --- a/composer.json +++ b/composer.json @@ -17,6 +17,7 @@ "laravel/tinker": "^2.7", "owen-it/laravel-auditing": "^13.0", "php-ffmpeg/php-ffmpeg": "^1.1", + "spatie/image-optimizer": "^1.6", "thiagoalessio/tesseract_ocr": "^2.12" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 070bb5e..1c710d0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6450b5aeb019101d8ac59d3e538eeb73", + "content-hash": "55915af70867f8005faeda07f9070b3d", "packages": [ { "name": "brick/math", @@ -3543,6 +3543,61 @@ ], "time": "2023-01-28T17:00:47+00:00" }, + { + "name": "spatie/image-optimizer", + "version": "1.6.4", + "source": { + "type": "git", + "url": "https://github.com/spatie/image-optimizer.git", + "reference": "d997e01ba980b2769ddca2f00badd3b80c2a2512" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/image-optimizer/zipball/d997e01ba980b2769ddca2f00badd3b80c2a2512", + "reference": "d997e01ba980b2769ddca2f00badd3b80c2a2512", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "php": "^7.3|^8.0", + "psr/log": "^1.0 | ^2.0 | ^3.0", + "symfony/process": "^4.2|^5.0|^6.0" + }, + "require-dev": { + "pestphp/pest": "^1.21", + "phpunit/phpunit": "^8.5.21|^9.4.4", + "symfony/var-dumper": "^4.2|^5.0|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\ImageOptimizer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Easily optimize images using PHP", + "homepage": "https://github.com/spatie/image-optimizer", + "keywords": [ + "image-optimizer", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/image-optimizer/issues", + "source": "https://github.com/spatie/image-optimizer/tree/1.6.4" + }, + "time": "2023-03-10T08:43:19+00:00" + }, { "name": "spatie/temporary-directory", "version": "2.1.1", diff --git a/public/media.php b/public/media.php index dbd30e3..83c0708 100644 --- a/public/media.php +++ b/public/media.php @@ -8,51 +8,72 @@ if (isset($_GET['url'])) { } if ($filepath !== false && strlen($filepath) > 0 && strpos($_GET['url'], 'uploads/') === 0 && is_file($filepath)) { - $image = imagecreatefromstring(file_get_contents($filepath)); - - $newWidth = (isset($_GET['w']) ? intval($_GET['w']) : -1); - $newHeight = (isset($_GET['h']) ? intval($_GET['h']) : -1); - - if($newWidth != -1 || $newHeight != -1) { - $width = imagesx($image); - $height = imagesy($image); - - $aspectRatio = $width / $height; - - if($newWidth == -1) { - $newWidth = intval($newHeight * $aspectRatio); + if(isset($_GET['size'])) { + $availableSizes = ['thumb', 'medium', 'large']; // we ignore full as its the original file + $requestedSize = strtolower($_GET['size']); + $requestedSizeIndex = array_search($requestedSize, $availableSizes); + + // Loop through the array from the requested size index + if($requestedSizeIndex !== false) { + for ($i = $requestedSizeIndex; $i < count($availableSizes); $i++) { + $sizePath = pathinfo($filepath, PATHINFO_DIRNAME) . '/' . pathinfo($filepath, PATHINFO_FILENAME) . "-$availableSizes[$i]." . pathinfo($filepath, PATHINFO_EXTENSION); + if (file_exists($sizePath)) { + $filepath = $sizePath; + break; + } + } } - if($newHeight == -1) { - $newHeight = intval($newWidth / $aspectRatio); - } - - $newImage = imagecreatetruecolor($newWidth, $newHeight); - imagecopyresampled($newImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height); - - // Output the resized image to the browser - $mime_type = mime_content_type($_GET['url']); - header('Content-Type: ' . $mime_type); - switch($mime_type) { - case "image/jpeg": - imagejpeg($newImage); - break; - case "image/gif": - imagegif($newImage); - break; - case "image/png": - imagepng($newImage); - break; - } - imagedestroy($newImage); - } else { // Output the original image to the browser header('Content-Type: '. mime_content_type($filepath)); readfile($filepath); - } + } else { + $newWidth = (isset($_GET['w']) ? intval($_GET['w']) : -1); + $newHeight = (isset($_GET['h']) ? intval($_GET['h']) : -1); - // Clean up the image resources - imagedestroy($image); + if($newWidth != -1 || $newHeight != -1) { + $image = imagecreatefromstring(file_get_contents($filepath)); + + $width = imagesx($image); + $height = imagesy($image); + + $aspectRatio = $width / $height; + + if($newWidth == -1) { + $newWidth = intval($newHeight * $aspectRatio); + } + + if($newHeight == -1) { + $newHeight = intval($newWidth / $aspectRatio); + } + + $newImage = imagecreatetruecolor($newWidth, $newHeight); + imagecopyresampled($newImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height); + + // Output the resized image to the browser + $mime_type = mime_content_type($_GET['url']); + header('Content-Type: ' . $mime_type); + switch($mime_type) { + case "image/jpeg": + imagejpeg($newImage); + break; + case "image/gif": + imagegif($newImage); + break; + case "image/png": + imagepng($newImage); + break; + } + imagedestroy($newImage); + + // Clean up the image resources + imagedestroy($image); + } else { + // Output the original image to the browser + header('Content-Type: '. mime_content_type($filepath)); + readfile($filepath); + } + } } else { // Return a 404 error header($_SERVER["SERVER_PROTOCOL"] . " 404 Not Found");