pixelandtonic/imagine
Imagine is a Laravel package that streamlines image handling and transformations using the Imagine library. Generate thumbnails, crop, resize, and apply filters with a clean API for integrating image processing into your app’s workflows.
Installation
composer require pixelandtonic/imagine
Add the service provider to config/app.php under providers:
Pixelandtonic\Imagine\ImagineServiceProvider::class,
Basic Usage Initialize the service in a controller or service class:
use Pixelandtonic\Imagine\Imagine;
public function __construct(Imagine $imagine)
{
$this->imagine = $imagine;
}
First Use Case: Resizing an Image
$image = $this->imagine->open(public_path('images/original.jpg'));
$image->resize(300, 200); // Width, height
$image->save(public_path('images/resized.jpg'));
Configuration
Check config/imagine.php for default settings (e.g., GD, Imagick, or Gmagick drivers). Set your preferred driver:
'driver' => 'imagick', // or 'gd', 'gmagick'
public function processImage(Request $request)
{
$image = $this->imagine->open($request->file('image')->path());
$image->resize(800, null, function ($constraint) {
$constraint->aspectRatio();
$constraint->upscale();
});
$image->save(public_path('uploads/' . $request->file('image')->hashName()));
}
Create a dedicated service class:
namespace App\Services;
use Pixelandtonic\Imagine\Imagine;
class ImageService {
protected $imagine;
public function __construct(Imagine $imagine)
{
$this->imagine = $imagine;
}
public function generateThumbnail($path, $width, $height)
{
$image = $this->imagine->open($path);
$image->resize($width, $height);
return $image->getImage();
}
}
Use Laravel queues to handle heavy processing:
use App\Jobs\ProcessImageJob;
ProcessImageJob::dispatch($imagePath, $newDimensions);
Job class:
public function handle()
{
$image = $this->imagine->open($this->imagePath);
$image->resize($this->width, $this->height);
$image->save(public_path('processed/' . $this->imagePath));
}
Use Laravel’s storage system for flexibility:
use Illuminate\Support\Facades\Storage;
$image = $this->imagine->open(Storage::path('images/original.jpg'));
$image->resize(400, 400);
$image->save(Storage::path('images/thumbnail.jpg'));
Create middleware to auto-process images on upload:
public function handle($request, Closure $next)
{
if ($request->hasFile('image')) {
$image = $this->imagine->open($request->file('image')->path());
$image->resize(1024, 1024);
$image->save($request->file('image')->path());
}
return $next($request);
}
Listen to filesystem events to process images post-upload:
Storage::disk('public')->addListener('after', function ($event) {
if ($event->path()->endsWith('.jpg') || $event->path()->endsWith('.png')) {
$image = $this->imagine->open(storage_path('app/' . $event->path()));
$image->resize(600, 600);
$image->save(storage_path('app/thumbs/' . $event->path()));
}
});
Use Laravel’s cache to avoid reprocessing:
$cacheKey = 'thumbnail_' . md5($originalPath);
$thumbnailPath = Cache::remember($cacheKey, now()->addDays(7), function () use ($originalPath) {
$image = $this->imagine->open($originalPath);
$image->resize(200, 200);
return $image->save(public_path('thumbs/' . basename($originalPath)));
});
php -m | grep -E 'gd|imagick'
php.ini and restart the server.memory_limit. Increase it temporarily:
ini_set('memory_limit', '512M');
chmod -R 775 storage/app/public
$image->resize(300, 300, function ($constraint) {
$constraint->aspectRatio(); // Preserve aspect ratio
});
Inspect image properties before/after processing:
$image = $this->imagine->open($path);
\Log::info('Original dimensions:', [
'width' => $image->getSize()->getWidth(),
'height' => $image->getSize()->getHeight(),
]);
Use try-catch to handle invalid files:
try {
$image = $this->imagine->open($path);
} catch (\ImagickException $e) {
\Log::error('Failed to open image: ' . $e->getMessage());
}
Ensure paths are correct and directories exist:
$directory = dirname(public_path('images/processed.jpg'));
if (!file_exists($directory)) {
mkdir($directory, 0777, true);
}
Extend the library by creating custom filters:
namespace App\Filters;
use Pixelandtonic\Imagine\Filters\FilterInterface;
class RoundedCornersFilter implements FilterInterface {
public function apply($image)
{
$image->resizeCanvas(300, 300, 'white');
$image->draw()->rectangle(
0, 0, 300, 300,
function ($draw) {
$draw->stroke('#000');
$draw->radius(20);
}
);
return $image;
}
}
Register the filter in ImagineServiceProvider:
$this->app->bind('app.filters.rounded-corners', function () {
return new \App\Filters\RoundedCornersFilter();
});
Override the default driver in runtime:
$imagine = new Imagine();
$imagine->use(\Imagine\Gd\Imagine::class); // Switch to GD
Dispatch events before/after processing:
event(new ImageProcessingEvent($image, 'resize'));
Listen to the event in an observer:
public function handle(ImageProcessingEvent $event)
{
\Log::info('Processing image: ' . $event->operation);
}
Process images during asset compilation:
mix.js('app.js', 'public/js')
.then(() => {
const { Imagine } = require('pixelandtonic/imagine');
const imagine = new Imagine();
// Process images programmatically
});
How can I help you explore Laravel packages today?