danihidayatx/image-optimizer
A fork of joshembling/image-optimizer for Filament v3, v4 and v5 and Laravel 10 through 13. It adds optimize and resize methods to FileUpload and SpatieMediaLibraryFileUpload, compressing and converting images before they reach your database or S3 bucket, saving disk space.
Installation:
composer require danihidayatx/image-optimizer
Publish the config (optional):
php artisan vendor:publish --provider="Danihidayatx\ImageOptimizer\ImageOptimizerServiceProvider" --tag="image-optimizer-config"
First Use Case:
Replace your standard FileUpload component with the optimized version in a Filament resource or page:
use Danihidayatx\ImageOptimizer\Components\FileUpload;
FileUpload::make('image')
->image()
->optimize() // Add this line
->required(),
config/image-optimizer.php (for customizing optimization settings like quality, formats, etc.).optimize(), optimizeWith() (for custom presets), and optimizeBeforeSave() (for pre-save hooks).Basic Optimization:
FileUpload::make('avatar')
->image()
->optimize() // Applies default settings (WebP, 80% quality)
->directory('avatars'),
Custom Presets:
Define a preset in config/image-optimizer.php:
'presets' => [
'thumbnails' => [
'quality' => 70,
'format' => 'jpg',
->width' => 300,
'height' => 300,
],
],
Use it in your component:
FileUpload::make('thumbnail')
->optimizeWith('thumbnails'),
Dynamic Optimization: Use closures for runtime logic (e.g., conditional optimization):
FileUpload::make('document')
->optimizeBeforeSave(fn ($file) => $file->getMimeType() === 'image/jpeg'),
Integration with Spatie Media Library:
Extend the SpatieMediaLibraryFileUpload component:
use Danihidayatx\ImageOptimizer\Components\SpatieMediaLibraryFileUpload;
SpatieMediaLibraryFileUpload::make('gallery')
->optimize()
->collection('images'),
Batch Processing: Optimize existing files post-upload via a job/queue:
use Danihidayatx\ImageOptimizer\Facades\ImageOptimizer;
ImageOptimizer::optimizeExisting($model->getMedia('images')->first()->getPath());
Custom Optimizers:
Extend the Optimizer class to add support for new formats/tools (e.g., AVIF):
namespace App\Optimizers;
use Danihidayatx\ImageOptimizer\Contracts\Optimizer;
class AvifOptimizer implements Optimizer {
public function optimize($filePath, array $options): string {
// Custom logic
}
}
Register it in config/image-optimizer.php:
'optimizers' => [
'avif' => App\Optimizers\AvifOptimizer::class,
],
Filament Panels: Reuse the optimized component across multiple panels by publishing assets and sharing the component class.
Format Limitations:
format in presets to avoid surprises:
'presets' => [
'fallback' => ['format' => 'jpg'],
],
Memory/Performance:
FileUpload::make('hero')
->optimize()
->queueOptimization(), // Add this
S3/Cloud Storage:
public disk for web-accessible files).Storage::makeDirectory()).Filament v4/v5 Quirks:
optimize() directly on FileUpload.FileUpload component due to API changes. Check the changelog.Original File Retention:
optimizeBeforeSave() to duplicate the file first:
FileUpload::make('backup_original')
->optimizeBeforeSave(fn ($file) => $file->duplicate()->store()),
Log Optimization:
Enable debug mode in config/image-optimizer.php:
'debug' => env('IMAGE_OPTIMIZER_DEBUG', false),
Logs will appear in storage/logs/laravel.log.
Validate Files:
Use optimizeBeforeSave() to validate files before processing:
FileUpload::make('profile_pic')
->optimizeBeforeSave(fn ($file) => $file->isValid() || throw new \Exception('Invalid image')),
Custom Directories:
Override the default optimized directory per component:
FileUpload::make('logo')
->optimize()
->directory('logos/optimized'),
Post-Optimization Actions:
Hook into the optimized event:
use Danihidayatx\ImageOptimizer\Events\ImageOptimized;
ImageOptimized::dispatch($optimizedPath, $originalPath);
Fallback for Unsupported Tools:
Configure fallbacks in config/image-optimizer.php:
'fallbacks' => [
'webp' => 'jpg', // Fallback to JPEG if WebP fails
],
Testing: Mock the optimizer in tests:
$this->mock(Danihidayatx\ImageOptimizer\Contracts\Optimizer::class, function ($mock) {
$mock->shouldReceive('optimize')->andReturn('optimized_path.jpg');
});
Combine with Filament Actions: Add a bulk-optimize action to resources:
use Danihidayatx\ImageOptimizer\Facades\ImageOptimizer;
Action::make('Optimize Images')
->action(fn () => ImageOptimizer::optimizeAll($this->getMedia('images'))),
Dynamic Quality: Adjust quality based on file size:
FileUpload::make('product_image')
->optimizeBeforeSave(fn ($file) => [
'quality' => $file->getSize() > 2000 ? 60 : 80,
]),
Laravel Vapor:
Ensure your Vapor config includes the optimized directory in the public directory for direct uploads.
How can I help you explore Laravel packages today?