intervention/image-laravel
Laravel integration for Intervention Image. Provides a service provider, facade, and publishable config (config/image.php) to set a global GD/Imagick driver and options. Install via Composer and configure once for consistent image processing across your app.
Installation:
composer require intervention/image-laravel
Publish Configuration (optional but recommended for customization):
php artisan vendor:publish --provider="Intervention\Image\Laravel\ServiceProvider"
This generates config/image.php with default settings (GD driver, auto-orientation, etc.).
First Use Case: Process an uploaded image in a route:
use Intervention\Image\Laravel\Facades\Image;
Route::post('/upload', function (Request $request) {
$image = Image::make($request->file('image'))
->resize(800, 600)
->save(public_path('processed.jpg'));
});
Intervention\Image\Laravel\Facades\Image (central entry point).config/image.php (driver, options like autoOrientation).response()->image($image, Format::WEBP) for HTTP responses.Upload & Process:
$image = Image::make($request->file('image'))
->fit(300, 300) // Maintain aspect ratio
->encode('jpg', 80); // Save with quality
Dynamic Thumbnails:
$thumbs = collect([200, 400, 800])->map(fn($size) =>
Image::make($original)
->resize($size, null, function ($constraint) {
$constraint->aspectRatio();
})
->toBase64()
);
Format Conversion:
$webp = Image::make($original)
->encode('webp', 75);
Storage Integration:
Storage::put('optimized/' . $filename, $image->encode());
Storage::disk('s3')->put() for cloud storage.ProcessImageJob::dispatch($imagePath, $resizeTo);
$request->validate(['image' => 'required|image|mimes:jpeg,png']);
Cache::remember("image_{$path}_{$width}x{$height}", now()->addHours(1), fn() =>
Image::make($path)->resize($width, $height)->encode()
);
Intervention\Image\Drivers\DriverInterface for specialized needs (e.g., GPU acceleration).public function handle(Request $request, Closure $next) {
if ($request->hasFile('image')) {
$request->merge(['image' => Image::make($request->file('image'))->resize(1024, 768)]);
}
return $next($request);
}
response()->image() macro for optimized delivery:
return response()->image($image, Format::WEBP, quality: 60)
->header('Content-Disposition', 'inline; filename="optimized.jpg"');
Driver Conflicts:
php-gd or php-imagick). Test with:
php artisan config:clear && php -m | grep -E 'gd|imagick'
config/image.php if primary fails.Memory Limits:
memory_limit. Increase temporarily:
ini_set('memory_limit', '512M');
->resize() before ->encode() to reduce memory usage.Console Context:
response()->image() macro is disabled in Artisan commands (see #18). Use ->encode() directly instead.File Extensions:
->encodeUsingFileExtension() or specify formats explicitly to avoid silent failures:
$image->encode('jpg'); // Explicit
$image->encodeUsingFileExtension('png'); // From filename
Exif Data:
autoOrientation may rotate images unexpectedly. Disable if needed:
config(['image.options.autoOrientation' => false]);
try {
$image->resize(1000, 1000);
} catch (\Intervention\Image\Exception\NotWritableException $e) {
Log::error('Image write failed: ' . $e->getMessage());
}
if (!$request->file('image')->isValidImage()) {
throw new \Exception('Invalid image file');
}
$driver = app(\Intervention\Image\ImageManager::class)->driver();
Log::info('Using driver:', [$driver::class]);
Custom Image Classes:
Extend Intervention\Image\Image for domain-specific methods:
class ProductImage extends \Intervention\Image\Image {
public function addWatermark($watermarkPath) {
$this->insert($watermarkPath, 'center');
}
}
Register via service provider:
$manager->extend('product', function () {
return new ProductImage();
});
Event Listeners: Trigger events for processed images:
event(new ImageProcessed($imagePath, $newDimensions));
Testing: Mock the facade in tests:
Image::shouldReceive('make')
->once()
->andReturn($mockImage);
.env to override driver:
IMAGE_DRIVER=Intervention\Image\Drivers\Imagick\Driver::class
config/image.php:
'options' => [
'quality' => 80, // Default for encode()
]
decodeAnimation for static images to save memory:
'options' => [
'decodeAnimation' => false,
]
->stream() for large files:
return response()->stream(function () use ($image) {
echo $image->stream('jpg', 70);
});
foreach ($files as $file) {
try {
$image = Image::make($file)->resize(500, 500);
$image->save(storage_path("processed/{$file->hashName()}"));
} catch (\Exception $e) {
Log::error("Failed to process {$file->getClientOriginalName()}: {$e->getMessage()}");
}
}
How can I help you explore Laravel packages today?