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 Laravel Package

spatie/image

Expressive PHP image manipulation with a fluent API. Resize, crop, rotate, sharpen, adjust brightness/contrast, apply filters, set quality and orientation, and convert formats. Load, chain operations, and save to a new file or overwrite.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/image
    

    Ensure PHP extensions gd, imagick, or vips are enabled (required for drivers).

  2. First Use Case:

    use Spatie\Image\Image;
    
    // Load, resize, and save an image
    Image::load(public_path('original.jpg'))
        ->resize(800, 600)
        ->save(public_path('resized.jpg'));
    
  3. Key Entry Points:

    • Documentation: spatie.be/docs/image
    • Driver Selection: Configure in config/image.php (default: gd if imagick unavailable).
    • Common Methods: load(), resize(), crop(), filter(), save().

Implementation Patterns

Core Workflows

  1. Dynamic Image Processing in Controllers:

    public function uploadImage(Request $request) {
        $image = Image::load($request->file('image')->path())
            ->fit(1200, 800, 'top-left')
            ->sharpen(10)
            ->save(public_path('processed/' . $request->file('image')->hashName()));
        return response()->json(['path' => $image]);
    }
    
  2. Queue-Based Processing (for large files):

    // In controller
    ProcessImageJob::dispatch($request->file('image'));
    
    // Job class
    public function handle() {
        Image::load(storage_path('temp/' . $this->filename))
            ->resize(1024, null, function ($constraint) {
                $constraint->aspectRatio();
            })
            ->save(storage_path('processed/' . $this->filename));
    }
    
  3. Reusable Image Services:

    class ImageService {
        public function generateThumbnail($path, $width) {
            return Image::load($path)
                ->resize($width, null, function ($constraint) {
                    $constraint->aspectRatio();
                })
                ->save();
        }
    }
    
  4. Integration with Storage:

    use Illuminate\Support\Facades\Storage;
    
    $image = Image::load(Storage::path('images/original.jpg'))
        ->watermark(public_path('watermark.png'), 'bottom-right', 0.2)
        ->save(Storage::path('images/processed.jpg'));
    
  5. Batch Processing:

    $files = Storage::files('images/raw');
    foreach ($files as $file) {
        Image::load($file)
            ->greyscale()
            ->save(str_replace('raw', 'processed', $file));
    }
    

Advanced Patterns

  • Conditional Processing:

    $image = Image::load($path);
    if ($request->has('crop')) {
        $image->crop($request->crop['width'], $request->crop['height']);
    }
    $image->save();
    
  • Driver-Specific Optimizations:

    // Force Imagick for high-quality operations
    Image::load($path)->useDriver('imagick')->resize(2000, null);
    
  • Event-Based Processing (e.g., uploaded events):

    public function handle(Uploaded $event) {
        Image::load($event->file->path())
            ->fit(1000, 1000)
            ->save($event->file->path());
    }
    

Gotchas and Tips

Pitfalls

  1. Driver Dependencies:

    • GD: Default fallback; limited EXIF support (e.g., rotated images may need manual fixes).
    • Imagick: Best for advanced features (e.g., pixelate(), focalCrop()), but requires imagick PHP extension.
    • VIPS: High performance for large images, but less common (requires vips extension).
    • Fix: Explicitly set the driver:
      Image::load($path)->useDriver('imagick')->resize(...);
      
  2. File Path Handling:

    • Absolute Paths: Always use public_path(), storage_path(), or realpath() to avoid issues.
    • Relative Paths: May break in shared hosting or CI environments.
  3. EXIF Orientation:

    • GD driver may mishandle rotated images (e.g., from mobile cameras). Use imagick or manually fix:
      Image::load($path)->orientation()->save();
      
  4. Memory Limits:

    • Large images (e.g., >10MB) may hit PHP’s memory_limit. Increase it temporarily:
      ini_set('memory_limit', '512M');
      Image::load($largeFile)->resize(...)->save();
      
  5. Format-Specific Issues:

    • PNG: GD may drop transparency on resize. Use imagick or vips.
    • WebP: Ensure webp support is enabled in GD/Imagick (gd.webp in php.ini).
    • Fix: Specify format explicitly:
      Image::load($path)->resize()->save()->format('webp');
      
  6. Race Conditions:

    • Overwriting files during concurrent requests can corrupt images. Use unique filenames:
      $filename = uniqid() . '.jpg';
      Image::load($path)->save(public_path("processed/{$filename}"));
      

Debugging Tips

  1. Check Driver Availability:

    if (!Image::drivers()->has('imagick')) {
        throw new \RuntimeException('Imagick driver not available');
    }
    
  2. Validate Image Data:

    try {
        $image = Image::load($path);
        // Process image
    } catch (\Spatie\Image\Exceptions\InvalidPath $e) {
        Log::error("Invalid image path: {$path}");
    }
    
  3. Log Driver Usage:

    Image::load($path)->useDriver('imagick')->on('save', function () {
        Log::debug('Saved image with Imagick driver');
    })->save();
    
  4. Test Locally with storage:link: Ensure processed images are accessible via public symlink:

    php artisan storage:link
    

Performance Optimizations

  1. Cache Processed Images:

    $cachePath = storage_path("cache/{$hash}.jpg");
    if (!file_exists($cachePath)) {
        Image::load($path)->resize()->save($cachePath);
    }
    
  2. Use vips for Large Files:

    Image::load($path)->useDriver('vips')->resize()->save();
    
  3. Disable Unused Filters: Avoid chaining unnecessary methods (e.g., greyscale()->sharpen() if only resizing is needed).

Extension Points

  1. Custom Drivers: Implement Spatie\Image\Contracts\Driver for proprietary formats:

    class MyDriver implements Driver {
        public function load($path) { /* ... */ }
        public function save($path) { /* ... */ }
        // Implement other methods
    }
    

    Register via:

    Image::extend('my_driver', function () {
        return new MyDriver();
    });
    
  2. Override Default Behavior: Extend the Image class:

    class CustomImage extends \Spatie\Image\Image {
        public function customFilter() {
            $this->sepia();
            return $this;
        }
    }
    

    Use via:

    CustomImage::load($path)->customFilter()->save();
    
  3. Hooks for Post-Processing: Use the on() method to inject logic:

    Image::load($path)
        ->on('save', function ($image) {
            // Add metadata, log, etc.
        })
        ->resize()
        ->save();
    

Configuration Quirks

  1. Default Driver: Set in config/image.php:

    'default' => env('IMAGE_DRIVER', 'gd'),
    

    Override globally:

    Image::useDriver('imagick');
    
  2. Quality Settings:

    • GD: quality() (1–100, default: 75).
    • Imagick: quality() (1–100, default: 92).
    • VIPS: quality() (1–100, default: 90).
  3. Format Preservation: Use format() to enforce output format:

    Image::load($path)->resize()->format('webp')->save();
    

Common Anti-Patterns

  1. Chaining Without Saving:

    // ❌ Avoid: No save() call
    Image::load($path)->resize()->crop();
    
  2. **Ignoring Driver Fail

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.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai