Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Image Optimizer Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require danihidayatx/image-optimizer
    

    Publish the config (optional):

    php artisan vendor:publish --provider="Danihidayatx\ImageOptimizer\ImageOptimizerServiceProvider" --tag="image-optimizer-config"
    
  2. 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(),
    

Where to Look First

  • Config File: config/image-optimizer.php (for customizing optimization settings like quality, formats, etc.).
  • Component Methods: Focus on optimize(), optimizeWith() (for custom presets), and optimizeBeforeSave() (for pre-save hooks).
  • Documentation: The README’s Usage section for quick examples.

Implementation Patterns

Core Workflows

  1. Basic Optimization:

    FileUpload::make('avatar')
        ->image()
        ->optimize() // Applies default settings (WebP, 80% quality)
        ->directory('avatars'),
    
  2. 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'),
    
  3. Dynamic Optimization: Use closures for runtime logic (e.g., conditional optimization):

    FileUpload::make('document')
        ->optimizeBeforeSave(fn ($file) => $file->getMimeType() === 'image/jpeg'),
    
  4. Integration with Spatie Media Library: Extend the SpatieMediaLibraryFileUpload component:

    use Danihidayatx\ImageOptimizer\Components\SpatieMediaLibraryFileUpload;
    
    SpatieMediaLibraryFileUpload::make('gallery')
        ->optimize()
        ->collection('images'),
    

Advanced Patterns

  • 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.


Gotchas and Tips

Pitfalls

  1. Format Limitations:

    • The package defaults to WebP (smallest size) but falls back to JPEG/PNG if unsupported.
    • Tip: Explicitly set format in presets to avoid surprises:
      'presets' => [
          'fallback' => ['format' => 'jpg'],
      ],
      
  2. Memory/Performance:

    • Large images or batch processing may hit memory limits. Use queues for async optimization:
      FileUpload::make('hero')
          ->optimize()
          ->queueOptimization(), // Add this
      
  3. S3/Cloud Storage:

    • Ensure your storage disk is configured to handle optimized files (e.g., public disk for web-accessible files).
    • Gotcha: Directories must exist on the remote storage before upload (use Storage::makeDirectory()).
  4. Filament v4/v5 Quirks:

    • v4: Use optimize() directly on FileUpload.
    • v5: May require wrapping in a FileUpload component due to API changes. Check the changelog.
  5. Original File Retention:

    • The package deletes the original after optimization. To keep backups, use optimizeBeforeSave() to duplicate the file first:
      FileUpload::make('backup_original')
          ->optimizeBeforeSave(fn ($file) => $file->duplicate()->store()),
      

Debugging

  • 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')),
    

Extension Points

  1. Custom Directories: Override the default optimized directory per component:

    FileUpload::make('logo')
        ->optimize()
        ->directory('logos/optimized'),
    
  2. Post-Optimization Actions: Hook into the optimized event:

    use Danihidayatx\ImageOptimizer\Events\ImageOptimized;
    
    ImageOptimized::dispatch($optimizedPath, $originalPath);
    
  3. Fallback for Unsupported Tools: Configure fallbacks in config/image-optimizer.php:

    'fallbacks' => [
        'webp' => 'jpg', // Fallback to JPEG if WebP fails
    ],
    
  4. Testing: Mock the optimizer in tests:

    $this->mock(Danihidayatx\ImageOptimizer\Contracts\Optimizer::class, function ($mock) {
        $mock->shouldReceive('optimize')->andReturn('optimized_path.jpg');
    });
    

Pro Tips

  • 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.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator