Weave Code
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

spatie/image-optimizer

Optimize PNG, JPG, WebP, AVIF, SVG and GIF images in PHP by running them through a chain of installed binaries (jpegoptim, optipng, pngquant, svgo, etc.). Automatically detects available tools and overwrites files with smaller optimized versions.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the Package

    composer require spatie/image-optimizer
    

    For Laravel-specific integration, use:

    composer require spatie/laravel-image-optimizer
    
  2. Install Optimization Tools Choose your OS and run the relevant commands from the README. Example for Ubuntu/Debian:

    sudo apt-get install jpegoptim optipng pngquant gifsicle webp libavif-bin
    npm install -g svgo
    
  3. First Use Case Optimize an image in-place:

    use Spatie\ImageOptimizer\OptimizerChainFactory;
    
    $optimizer = OptimizerChainFactory::create();
    $optimizer->optimize(storage_path('app/public/image.jpg'));
    

Where to Look First


Implementation Patterns

Core Workflows

  1. Basic Optimization

    $optimizer = OptimizerChainFactory::create();
    $optimizer->optimize($inputPath, $outputPath); // Overwrite or save to new path
    
  2. Batch Processing Use Laravel's Storage facade or collect() to process multiple files:

    $files = Storage::files('public/images');
    foreach ($files as $file) {
        $optimizer->optimize($file);
    }
    
  3. Queue Optimization Jobs For large-scale processing, dispatch jobs:

    use Spatie\ImageOptimizer\Jobs\OptimizeImage;
    
    OptimizeImage::dispatch($imagePath)->onQueue('optimize');
    
  4. Custom Chains Override default optimizers for specific needs:

    $chain = (new OptimizerChain)
        ->addOptimizer(new Jpegoptim(['--strip-all', '--max=90']))
        ->addOptimizer(new Pngquant(['--force', '--speed=1']));
    $chain->optimize($path);
    

Integration Tips

  • Laravel Filesystem: Use Storage::disk('public')->put() to save optimized files.
  • Artisan Commands: Create a custom command for CLI optimization:
    use Spatie\ImageOptimizer\OptimizerChainFactory;
    
    class OptimizeCommand extends Command {
        protected $signature = 'images:optimize {path}';
        public function handle() {
            $optimizer = OptimizerChainFactory::create();
            $optimizer->optimize($this->argument('path'));
        }
    }
    
  • Event Listeners: Trigger optimizations on file uploads:
    use Spatie\ImageOptimizer\OptimizerChainFactory;
    
    class HandleUpload {
        public function handle() {
            $optimizer = OptimizerChainFactory::create();
            $optimizer->optimize($uploadedFilePath);
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Missing Binaries

    • Symptom: No optimization occurs silently.
    • Fix: Verify binaries are installed and in $PATH. Use which jpegoptim (Linux/Mac) or check where jpegoptim (Windows).
    • Debug: Enable logging to see which tools are detected:
      $optimizer->useLogger(new \Monolog\Logger('optimizer', [new \Monolog\Handler\StreamHandler(storage_path('logs/optimizer.log'))]));
      
  2. Permission Issues

    • Symptom: Optimizer fails with "Permission denied" errors.
    • Fix: Ensure the web server user (e.g., www-data, nginx) has write permissions:
      chmod -R 755 storage/app/public
      chown -R www-data:www-data storage/app/public
      
  3. SVGO Breaking SVGs

    • Symptom: Optimized SVGs render incorrectly.
    • Fix: Exclude problematic plugins or use a custom SVGO config:
      $optimizerChain->addOptimizer(new Svgo(['--config', __DIR__.'/svgo.config.js']));
      
  4. Timeouts

    • Symptom: Large images time out.
    • Fix: Increase timeout for specific optimizers:
      $optimizer->setTimeout(30); // 30 seconds per optimizer
      

Debugging Tips

  • Check Binary Paths: Override paths if binaries are in non-standard locations:
    $optimizerChain->setBinaryPath('jpegoptim', '/custom/path/jpegoptim');
    
  • Dry Run: Log commands without executing:
    $optimizer->useLogger(new class implements \Psr\Log\LoggerInterface {
        public function log($level, $message, array $context = []) {
            dump($message); // Inspect commands
        }
        // ... other required methods
    });
    
  • File Locking: Avoid concurrent optimizations on the same file (use flock or queues).

Extension Points

  1. Custom Optimizers Implement the Optimizer interface for new tools (e.g., Guetzli for JPEG):

    class GuetzliOptimizer implements Optimizer {
        public function binaryName(): string { return 'cjpeg -guetzli'; }
        public function canHandle(Image $image): bool { return $image->isJpeg(); }
        // ... other methods
    }
    
  2. Pre/Post-Processing Chain optimizers with Laravel events or middleware:

    event(new OptimizedImage($originalPath, $optimizedPath));
    
  3. Progress Tracking Use Laravel's ProgressBar for batch jobs:

    $bar = new ProgressBar($files->count());
    foreach ($files as $file) {
        $optimizer->optimize($file);
        $bar->advance();
    }
    

Configuration Quirks

  • Laravel Cache: Optimizer binaries are cached. Clear cache if binaries are updated:
    \Spatie\ImageOptimizer\OptimizerChain::forgetCachedBinaries();
    
  • Case Sensitivity: Binary names are case-sensitive on Linux (e.g., jpegoptim vs JpegOptim). Use lowercase in configs.
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.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle