intervention/image
Intervention Image is a PHP image handling and manipulation library for Laravel and other frameworks. Create, resize, crop, encode, and optimize images with a simple fluent API, supporting GD and Imagick, plus drivers and integrations for common storage and HTTP workflows.
Installation (PHP 8.3+ required):
composer require intervention/image:^4.0
Publish Laravel config (optional):
php artisan vendor:publish --provider="Intervention\Image\ImageServiceProvider" --tag=config
Basic Usage (Fluent API):
use Intervention\Image\Facades\Image;
$img = Image::make(public_path('images/original.jpg'))
->resize(300, 200)
->save(public_path('images/thumbnail.jpg'));
First Use Case (Dynamic Thumbnail Generation):
public function generateThumbnail($filename, $width = 300) {
return Image::make(storage_path("app/{$filename}"))
->resize($width, null, function ($constraint) {
$constraint->aspectRatio();
})
->save();
}
Key Files to Explore:
config/image.php: Driver configuration (GD/Imagick/libvips), quality settings, and cache paths.app/Providers/ImageServiceProvider.php: Laravel service provider for facades.public function responsiveImage($filename, $maxWidth = 1200) {
return Image::make(storage_path("app/{$filename}"))
->resize(new \Intervention\Image\Constraints\Dimension($maxWidth, null), function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
})
->encode('webp', 80)
->toResponse();
}
public function addWatermark($imagePath, $watermarkPath, $outputPath) {
$img = Image::make($imagePath);
$watermark = Image::make($watermarkPath)
->resize(200, null, function ($constraint) {
$constraint->aspectRatio();
})
->opacity(50);
$img->insert($watermark, 'center');
return $img->save($outputPath);
}
public function processUploadedImages($userId) {
$images = UserImage::where('user_id', $userId)
->where('processed', false)
->get();
foreach ($images as $image) {
ProcessImageJob::dispatch($image->path, $image->id);
}
}
// Job class
public function handle() {
$img = Image::make(storage_path("app/{$this->path}"))
->resize(800, null, function ($constraint) {
$constraint->aspectRatio();
})
->save();
UserImage::find($this->imageId)
->update(['processed' => true, 'path' => $img->path]);
}
public function getImage(Request $request, $filename) {
$path = storage_path("app/{$filename}");
$img = Image::make($path)
->resize(1024, null, function ($constraint) {
$constraint->aspectRatio();
});
return response($img->encode(), 200, [
'Content-Type' => $img->mime(),
'Cache-Control' => 'public, max-age=31536000',
]);
}
// In config/image.php
'drivers' => [
'gd' => [
'quality' => 90,
'interlace' => true,
'optimize' => true,
],
'imagick' => [
'quality' => 95,
'sampling' => 'Lanczos',
],
],
// Usage
$img = Image::make($path)
->driver('imagick') // Force Imagick for high-quality output
->resize(1500, null)
->save();
Driver Compatibility:
->driver('imagick') explicitly for consistent results.Memory Limits:
->stream() for direct output or process in chunks:
$img->stream(function ($image) {
return $image->resize(2000, 2000);
}, 'jpg', 80);
Path Handling:
->font() or ->insert() may break across environments.public_path()/storage_path().Animated Images:
->frameDelay() or ->optimize() for animations:
$img->optimize()->save();
Color Space Inconsistencies:
->colorize() or ->adjust() with explicit color spaces:
$img->colorize(200, 100, 50, 50); // RGBA
Inspect Image Data:
$img = Image::make($path);
dd($img->debug()); // Shows width, height, mime, and driver info
Check Driver Availability:
if (!Image::driversAvailable()) {
dd(Image::driversAvailable()); // Shows available drivers
}
Handle Exceptions Gracefully:
try {
$img = Image::make($path)->resize(100, 100);
} catch (\Intervention\Image\Exception\NotReadableException $e) {
Log::error("Image not readable: {$e->getMessage()}");
return response()->view('errors.image');
}
Cache Processed Images:
$img = Image::cache(function ($image) {
return $image->resize(800, 600)->sharpen(10);
}, 'memory', 3600); // Cache for 1 hour
Use Efficient Formats:
$img->encode('jpg', 80, ['progressive' => true]);
Batch Operations:
$images = collect([...]);
$processed = $images->map(function ($path) {
return Image::make($path)->resize(400, 400)->encode('webp', 70);
});
Custom Drivers:
\Intervention\Image\Driver\DriverInterface for custom backends.ImageManager::extend().Modify Constraints:
\Intervention\Image\Constraints\Constraint.Add Filters:
\Intervention\Image\Filter\FilterInterface for custom effects (e.g., blur, pixelate).Override Defaults:
config/image.php for global settings.Store Processed Images:
$path = $request->file('image')->store('processed', 'public');
$img = Image::make(storage_path("app/{$path}"))
->resize(1024, 1024)
->save();
Use Storage Facade:
$img = Image::make(storage_path('app/' . $request->file('image')->hashName()))
->resize(800, 800)
->save();
Queue Long-Running Tasks:
ProcessImageJob::dispatch($request->file('image'), $user->id);
Leverage Facades:
// Instead of:
$img = (new ImageManager())->gd()->read($path);
// Use:
$img = Image::make($path);
How can I help you explore Laravel packages today?