intervention/image
Intervention Image is a PHP image handling and manipulation library for Laravel and other frameworks. It provides a fluent API for resizing, cropping, encoding, watermarking, and optimizing images, with drivers for GD and Imagick and easy integration via service providers.
Installation:
composer require intervention/image
Ensure your server has either GD, Imagick, or libvips installed (GD is most common for Laravel).
Basic Usage:
use Intervention\Image\Facades\Image;
$img = Image::make(public_path('image.jpg'));
$img->resize(300, 200)->save(public_path('resized.jpg'));
First Use Case:
$thumb = Image::make(storage_path('original.jpg'))
->fit(150, 150)
->save(storage_path('thumb.jpg'));
Intervention\Image\Facades\Image (for quick usage)Intervention\Image\ImageManager (for advanced driver control)Image Manipulation Pipeline:
$image = Image::make($path)
->resize(800, null, function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
})
->rotate(10)
->text('Watermark', 10, 10, function ($font) {
$font->file(storage_path('fonts/arial.ttf'));
$font->color('#FFFFFF');
$font->align('center');
$font->valign('middle');
})
->save($outputPath);
Driver-Specific Optimizations:
// Use Imagick for high-quality operations (e.g., PDFs, advanced filters)
$manager = new \Intervention\Image\ImageManager(['driver' => 'imagick']);
$image = $manager->read($path)->resize(1024, 1024);
// Fallback to GD for memory efficiency
$gdImage = Image::gd()->make($path)->resize(300, 300);
Batch Processing:
$files = Storage::disk('s3')->files('images/originals/');
foreach ($files as $file) {
$img = Image::make(storage_path("tmp/{$file}"))
->resize(600, null, function ($constraint) {
$constraint->aspectRatio();
})
->save(storage_path("tmp/thumbs/{$file}"));
}
Dynamic Image Generation (e.g., Charts, QR Codes):
$canvas = Image::canvas(400, 300, '#FFFFFF');
$canvas->text('Dynamic Chart', 10, 10, function ($font) {
$font->size(24);
$font->color('#333');
});
$canvas->save(storage_path('dynamic_chart.png'));
Laravel Filesystem:
Use Storage::disk() to read/write images from S3, local storage, etc.
$img = Image::make(Storage::disk('s3')->path('image.jpg'));
Queued Jobs:
Offload heavy processing to queues (e.g., resizeImageJob):
ResizeImageJob::dispatch($originalPath, $thumbPath, 300, 300)->onQueue('images');
Middleware for Image Validation:
public function handle(Request $request, Closure $next) {
if ($request->hasFile('image')) {
$img = Image::make($request->file('image')->getRealPath());
if ($img->width() > 2000) {
abort(422, 'Image too large');
}
}
return $next($request);
}
Caching Processed Images: Use Laravel’s cache or Redis to store processed images:
$cacheKey = "thumb_{$originalPath}_{$width}x{$height}";
if (!Cache::has($cacheKey)) {
$img = Image::make($originalPath)->resize($width, $height);
Cache::put($cacheKey, $img->encode(), now()->addHours(1));
}
Driver Compatibility:
Image::gd() or Image::imagick() explicitly.pecl install vips).Memory Limits:
memory_limit.
Fix: Use Imagick’s setImageFormat() or chunk processing:
ini_set('memory_limit', '512M');
// OR
$image->resize(1024, 1024)->stream()->save($outputPath);
Transparency Issues:
->save()->withEncodingOptions(['png' => ['transparent' => true]]).Path Handling:
// ❌ Won't work (relative path)
$img->text('Hello', 10, 10, function ($font) {
$font->file('fonts/arial.ttf'); // Fails!
});
// ✅ Works
$fontPath = realpath(base_path('fonts/arial.ttf'));
$img->text('Hello', 10, 10, function ($font) use ($fontPath) {
$font->file($fontPath);
});
Animated GIFs/WEBP:
$manager = new \Intervention\Image\ImageManager(['driver' => 'imagick']);
$gif = $manager->read($path)->animate(10); // 10fps
Inspect Image Data:
$img = Image::make($path);
dd([
'width' => $img->width(),
'height' => $img->height(),
'mime' => $img->mime(),
'driver' => $img->driverName(),
'colors' => $img->colors(),
]);
Check Driver Availability:
if (!Image::driversAvailable()) {
dd('No drivers available! Install GD/Imagick.');
}
Handle Exceptions:
try {
$img = Image::make($path)->resize(100, 100);
} catch (\Intervention\Image\Exceptions\NotReadableException $e) {
Log::error("Image not readable: {$e->getMessage()}");
} catch (\Intervention\Image\Exceptions\NotWritableException $e) {
Log::error("Cannot save image: {$e->getMessage()}");
}
Validate File Types:
$mime = mime_content_type($path);
if (!in_array($mime, ['image/jpeg', 'image/png', 'image/webp'])) {
abort(422, 'Unsupported image type');
}
Custom Drivers:
Extend \Intervention\Image\Drivers\DriverInterface for proprietary formats.
Modifier Chaining: Create reusable modifier classes:
class WatermarkModifier {
public function __invoke($image) {
$watermark = Image::make(storage_path('watermark.png'));
return $image->insert($watermark, 'bottom-right', 10, 10);
}
}
// Usage:
$img->pipe(new WatermarkModifier());
Color Manipulation: Use the new color system (v4+):
$color = new \Intervention\Image\Colors\Rgb\Color(255, 0, 0);
$img->fill($color)->rectangle(10, 10, 50, 50);
Performance Tuning:
$img->encode('jpg', 80, ['progressive' => true]);
$img->encode('jpg', 80, ['strip' => true]);
Testing:
Use Mockery to test image logic without files:
How can I help you explore Laravel packages today?