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?