christyoga123 / image-optimizer
A fluent Laravel package for optimizing images - resize, convert formats (WebP, JPG, PNG, AVIF), and reduce file size while maintaining quality
Requires
- php: ^8.1
- illuminate/support: ^10.0|^11.0|^12.0
- intervention/image: ^3.0
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0|^10.0
- phpunit/phpunit: ^10.0|^11.0
README
A fluent Laravel package for optimizing images - resize, convert formats (WebP, JPG, PNG, AVIF), and reduce file size while maintaining quality.
Features
- ๐ผ๏ธ Format Conversion - Convert images to WebP, JPG, PNG, GIF, AVIF
- ๐ Smart Resize - Resize with max width/height while maintaining aspect ratio
- ๐๏ธ Quality Control - Adjustable quality settings for optimal file size
- ๐ง Fluent API - Chain methods for clean, readable code
- โ๏ธ Configurable - Publish and customize default settings
- ๐งน Auto Cleanup - Automatic temporary file cleanup
Requirements
- PHP 8.1+
- Laravel 10.x, 11.x, or 12.x
- GD Library or Imagick extension
Installation
Install the package via Composer:
composer require christyoga123/image-optimizer
The package will automatically register its service provider.
Publish Configuration (Optional)
php artisan vendor:publish --tag=image-optimizer-config
This will create a config/image-optimizer.php file with all available options.
Usage
Basic Usage
use Christyoga123\ImageOptimizer\ImageOptimizer; // Process uploaded file and get optimized temp path $tempPath = ImageOptimizer::make() ->toWebp() ->maxDimensions(1200, 1200) ->quality(85) ->process($uploadedFile); // Do something with the optimized file Storage::disk('public')->put('images/photo.webp', file_get_contents($tempPath));
Using Facade
use Christyoga123\ImageOptimizer\Facades\ImageOptimizer; $tempPath = ImageOptimizer::make() ->toWebp() ->maxWidth(800) ->process($request->file('image'));
From Request Input
$tempPath = ImageOptimizer::make() ->toJpg() ->quality(90) ->processFromRequest('photo'); if ($tempPath) { // File was uploaded and processed $user->update(['avatar' => Storage::putFile('avatars', $tempPath)]); }
From File Path
$tempPath = ImageOptimizer::make() ->toPng() ->maxDimensions(600, 600) ->processFromPath('/path/to/original/image.jpg');
With Default Settings
Apply all defaults from config at once:
$tempPath = ImageOptimizer::make() ->withDefaults() ->process($uploadedFile);
Get Size Comparison
$optimizer = ImageOptimizer::make() ->toWebp() ->quality(80) ->maxDimensions(1200, 1200); $tempPath = $optimizer->process($uploadedFile); $comparison = $optimizer->getSizeComparison($uploadedFile->getRealPath()); // Result: // [ // 'original_size' => 2500000, // 'optimized_size' => 450000, // 'saved_bytes' => 2050000, // 'saved_percentage' => 82.0 // ] echo "Saved: " . $optimizer->formatFileSize($comparison['saved_bytes']); // Output: "Saved: 2.00 MB"
Helper Methods
$optimizer = ImageOptimizer::make(); // Get sanitized filename for storage $filename = $optimizer->getOptimizedFilename($uploadedFile); // "my_photo.webp" // Get current format $format = $optimizer->getFormat(); // "webp" // Get temp file path $path = $optimizer->getTempPath(); // Manual cleanup (usually not needed - destructor handles this) $optimizer->cleanup();
Available Methods
Format Methods
| Method | Description |
|---|---|
format(string $format) |
Set output format (webp, jpg, png, gif, avif) |
toWebp() |
Convert to WebP format |
toJpg() |
Convert to JPEG format |
toPng() |
Convert to PNG format |
toGif() |
Convert to GIF format |
toAvif() |
Convert to AVIF format |
Resize Methods
| Method | Description |
|---|---|
maxWidth(int $width) |
Set maximum width (maintains aspect ratio) |
maxHeight(int $height) |
Set maximum height (maintains aspect ratio) |
maxDimensions(int $width, int $height) |
Set both max width and height |
Quality & Settings
| Method | Description |
|---|---|
quality(int $quality) |
Set quality 1-100 (affects jpg, webp, avif) |
tempDir(string $path) |
Set custom temporary directory |
withDefaults() |
Apply all defaults from config |
Process Methods
| Method | Description |
|---|---|
process(UploadedFile $file) |
Process uploaded file |
processUploadedFile(UploadedFile $file) |
Alias for process() |
processFromPath(string $path) |
Process from file path |
processFromRequest(string $inputName) |
Process from request input name |
Configuration
After publishing, you can customize these options in config/image-optimizer.php:
return [ // Image driver: 'gd' or 'imagick' 'driver' => env('IMAGE_OPTIMIZER_DRIVER', 'gd'), // Default output format 'format' => env('IMAGE_OPTIMIZER_FORMAT', 'webp'), // Default quality (1-100) 'quality' => env('IMAGE_OPTIMIZER_QUALITY', 85), // Default max dimensions (used with withDefaults()) 'max_width' => env('IMAGE_OPTIMIZER_MAX_WIDTH', 1200), 'max_height' => env('IMAGE_OPTIMIZER_MAX_HEIGHT', 1200), // Temporary directory for processed files 'temp_dir' => env('IMAGE_OPTIMIZER_TEMP_DIR', storage_path('app/temp')), ];
Integration Examples
With Spatie Media Library
use Christyoga123\ImageOptimizer\ImageOptimizer; // Optimize before adding to media collection $tempPath = ImageOptimizer::make() ->toWebp() ->maxDimensions(1200, 1200) ->quality(85) ->process($request->file('photo')); $model->addMedia($tempPath) ->usingFileName('optimized-photo.webp') ->toMediaCollection('photos');
With Laravel Storage
$optimizer = ImageOptimizer::make() ->toWebp() ->maxWidth(800); $tempPath = $optimizer->process($request->file('image')); $filename = $optimizer->getOptimizedFilename($request->file('image')); // Store to disk $path = Storage::disk('public')->putFileAs('uploads', $tempPath, $filename); return response()->json(['path' => $path]);
In Form Request
// app/Http/Requests/StorePhotoRequest.php public function passedValidation() { if ($this->hasFile('photo')) { $tempPath = ImageOptimizer::make() ->withDefaults() ->process($this->file('photo')); $this->merge([ 'optimized_photo_path' => $tempPath ]); } }
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security
If you discover any security related issues, please email christianuswibisono@gmail.com instead of using the issue tracker.
Credits
License
The MIT License (MIT). Please see License File for more information.