Cookbook
Image Processing Examples
Comprehensive examples of using the Glueful Framework's image processing capabilities
This document provides comprehensive examples of using the Glueful Framework's image processing capabilities powered by Intervention Image v3.
Basic Operations
Simple Resize
// Using helper function (recommended)
image('/path/to/photo.jpg')
->resize(800, 600)
->save('/path/to/resized.jpg');
// Using service injection
$processor = app(ImageProcessorInterface::class);
$result = $processor::make('/path/to/photo.jpg')
->resize(800, 600)
->save('/path/to/resized.jpg');
Maintain Aspect Ratio
// Resize by width (height auto-calculated)
image('/path/to/photo.jpg')
->resize(800, null) // maintain aspect ratio
->save('/path/to/resized.jpg');
// Or resize by height (width auto-calculated)
image('/path/to/photo.jpg')
->resize(null, 600) // maintain aspect ratio
->save('/path/to/resized.jpg');
Quality Control
// Set JPEG quality (1-100)
image('/path/to/photo.jpg')
->resize(800, 600)
->quality(85)
->save('/path/to/output.jpg');
// Format conversion with quality
image('/path/to/photo.png')
->format('webp')
->quality(80)
->save('/path/to/output.webp');
Advanced Operations
Cropping and Fitting
// Crop to exact dimensions from center
image('/path/to/photo.jpg')
->crop(400, 300, 100, 50) // width, height, x, y
->save('/path/to/cropped.jpg');
// Fit to exact dimensions (covers area and may crop edges)
image('/path/to/photo.jpg')
->fit(800, 600)
->save('/path/to/fitted.jpg');
Watermarking
// Add watermark to bottom-right
image('/path/to/photo.jpg')
->watermark('/path/to/logo.png', 'bottom-right', 50) // 50% opacity
->save('/path/to/watermarked.jpg');
// Different watermark position
image('/path/to/photo.jpg')
->watermark('/path/to/logo.png', 'top-left', 75)
->save('/path/to/watermarked.jpg');
Custom Modifications
// Apply custom Intervention operations via modify()
image('/path/to/photo.jpg')
->modify(function ($img) {
// Example: adjust brightness/contrast using Intervention methods
// $img->brightness(20)->contrast(15);
})
->save('/path/to/adjusted.jpg');
Caching Examples
Basic Caching
// Cache processed image for 24 hours
$imageData = image('/path/to/photo.jpg')
->resize(800, 600)
->quality(85)
->cached('photo-800x600', 86400)
->getImageData();
Cache Key Generation
// Automatic cache key based on operations
$processor = image('/path/to/photo.jpg')
->resize(800, 600)
->quality(85)
->cached(); // Auto-generates cache key
// Custom cache key with TTL
$processor = image('/path/to/photo.jpg')
->resize(800, 600)
->cached('custom-thumbnail-' . $userId, 3600);
Retrieve From Cache (and Serve)
use Glueful\Cache\CacheStore;
// Resolve cache store
/** @var CacheStore<mixed> $cache */
$cache = app('cache.store');
// Compose full cache key used by ImageProcessor::cached()
$prefix = (string) (config('image.cache.prefix', 'image_'));
$key = $prefix . 'photo-800x600';
// Try to serve from cache first
if ($cached = $cache->get($key)) {
header('Content-Type: ' . $cached['mime_type']);
echo $cached['image_data'];
return; // done
}
// Cache miss: process and cache
$imageData = image('/path/to/photo.jpg')
->resize(800, 600)
->quality(85)
->cached('photo-800x600', 86400)
->getImageData();
header('Content-Type: image/jpeg');
echo $imageData;
Invalidate Cached Variant
$prefix = (string) (config('image.cache.prefix', 'image_'));
$key = $prefix . 'photo-800x600';
app('cache.store')->delete($key);
// Note: cached() stores the processed result under a cache key; retrieval and // invalidation should be handled by your cache layer if needed.
Remote Image Processing
Basic Remote Processing
// Process remote image with security checks
try {
$result = image('https://example.com/photo.jpg')
->resize(800, 600)
->quality(85)
->cached('remote-photo-800x600')
->save('/path/to/local.jpg');
} catch (\Glueful\Exceptions\BusinessLogicException $e) {
// Handle validation/security/processing errors
echo "Image error: " . $e->getMessage();
}
Batch Processing
// Process multiple images efficiently
$urls = [
'https://example.com/photo1.jpg',
'https://example.com/photo2.jpg',
'https://example.com/photo3.jpg'
];
foreach ($urls as $index => $url) {
try {
image($url)
->resize(400, 300)
->cached("batch-photo-{$index}")
->save("/path/to/batch_{$index}.jpg");
} catch (Exception $e) {
// Log error and continue
error_log("Failed to process {$url}: " . $e->getMessage());
}
}
Working with Uploads
Process File Uploads
// In controller handling file upload
public function uploadImage(Request $request): Response
{
$uploadedFile = $request->getUploadedFiles()['image'] ?? null;
if (!$uploadedFile) {
return Response::error('No image uploaded');
}
try {
// Process uploaded file (use fromUpload for UploadedFileInterface)
$processedData = app(ImageProcessorInterface::class)
::fromUpload($uploadedFile)
->resize(1200, 800)
->quality(85)
->format('webp')
->cached('upload-' . uniqid())
->getImageData();
// Save to storage
$filename = 'processed_' . time() . '.webp';
file_put_contents(storage_path('images/' . $filename), $processedData);
return Response::success(['filename' => $filename]);
} catch (Exception $e) {
return Response::error('Image processing failed: ' . $e->getMessage());
}
}
Generate Multiple Sizes
// Create thumbnail variants from upload
$uploadedFile = $request->getUploadedFiles()['image'];
$processor = app(ImageProcessorInterface::class)::fromUpload($uploadedFile);
$sizes = [
'thumbnail' => [150, 150],
'medium' => [400, 300],
'large' => [800, 600],
'original' => [1200, 900]
];
$results = [];
foreach ($sizes as $size => $dimensions) {
$processed = $processor->clone()
->fit($dimensions[0], $dimensions[1])
->quality(85)
->cached("upload-{$size}-" . uniqid())
->getImageData();
$filename = "{$size}_" . time() . '.jpg';
file_put_contents(storage_path("images/{$filename}"), $processed);
$results[$size] = $filename;
}
Performance Optimization
Memory Efficient Processing
// Process large images efficiently
$processor = image('/path/to/large-image.jpg');
// Check dimensions before processing
if ($processor->getWidth() > 4000 || $processor->getHeight() > 4000) {
// Resize very large images first
$processor->resize(2000, 1500);
}
// Continue with normal processing
$result = $processor
->resize(800, 600)
->quality(85)
->save('/path/to/output.jpg');
Streaming for Large Files
// Stream large processed images
public function serveProcessedImage(string $path): void
{
$processor = image($path)
->resize(1200, 800)
->cached();
// Stream directly to output
$processor->stream([
'Content-Disposition' => 'inline; filename="processed.jpg"'
]);
}
Error Handling
Comprehensive Error Handling
try {
$result = image('/path/to/photo.jpg')
->resize(800, 600)
->quality(85)
->save('/path/to/output.jpg');
} catch (\Glueful\Exceptions\BusinessLogicException $e) {
// Validation/security/processing errors (format, size, dimensions, etc.)
error_log("Image error: " . $e->getMessage());
} catch (Exception $e) {
// Generic errors
error_log("Unexpected error: " . $e->getMessage());
}
Configuration Examples
Environment Variables
# Production settings
IMAGE_DRIVER=imagick
IMAGE_MAX_WIDTH=2048
IMAGE_MAX_HEIGHT=2048
IMAGE_MAX_FILESIZE=10M
IMAGE_JPEG_QUALITY=85
IMAGE_WEBP_QUALITY=80
IMAGE_CACHE_ENABLED=true
IMAGE_CACHE_TTL=86400
IMAGE_VALIDATE_MIME=true
IMAGE_CHECK_INTEGRITY=true
IMAGE_DISABLE_EXTERNAL_URLS=false
IMAGE_ALLOWED_DOMAINS=example.com,cdn.example.com
Custom Configuration in Services
// Custom image processor with specific settings
$processor = new ImageProcessor(
$imageManager,
$cache,
$security,
$logger,
[
'optimization' => [
'jpeg_quality' => 90,
'webp_quality' => 85,
],
'security' => [
'allowed_domains' => ['trusted-cdn.com'],
'validate_mime' => true,
],
'cache' => [
'enabled' => true,
'ttl' => 3600,
'prefix' => 'custom-images-',
]
]
);
Integration with Controllers
RESTful Image API
class ImageController extends BaseController
{
public function resize(Request $request): Response
{
$this->requirePermission('images.process');
$url = $request->get('url');
$width = (int) $request->get('width', 800);
$height = (int) $request->get('height', 600);
$quality = (int) $request->get('quality', 85);
try {
$imageData = image($url)
->resize($width, $height)
->quality($quality)
->cached("resize-{$width}x{$height}-q{$quality}")
->getImageData();
return Response::success([
'processed' => true,
'size' => strlen($imageData),
'data' => base64_encode($imageData)
]);
} catch (Exception $e) {
return Response::error('Processing failed: ' . $e->getMessage());
}
}
}
This completes the comprehensive examples for the Glueful Framework's image processing capabilities.