coderden / image-optimizer
Image optimization package for PHP with jpegoptim, pngquant support
Installs: 3
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/coderden/image-optimizer
Requires
- php: ^8.1
- ext-fileinfo: *
- symfony/process: ^6.0
README
A powerful PHP package for optimizing images using external tools like jpegoptim, pngquant, optipng, and pngcrush. Perfect for Laravel applications but can be used in any PHP project.
Features
- 🚀 Multiple optimizers: Support for jpegoptim, pngquant, optipng, and pngcrush
- 📊 Detailed metrics: Get compression ratio, saved bytes, and optimization statistics
- ⚙️ Flexible configuration: Per-image type settings with quality and optimization options
- 🔄 Batch processing: Optimize multiple images at once
- 🛡️ Error handling: Comprehensive exception system with detailed error information
- 📈 Performance: Optimizes images without quality loss (or configurable loss)
Requirements
- PHP 8.1 or higher
- External optimization tools installed:
jpegoptimfor JPEG imagespngquant,optipng, orpngcrushfor PNG images
Install Required Tools
Ubuntu/Debian:
sudo apt-get install jpegoptim pngquant optipng pngcrush
macOS (Homebrew):
brew install jpegoptim pngquant optipng pngcrush
CentOS/RHEL:
sudo yum install jpegoptim pngquant optipng pngcrush
Installation
For Standalone PHP Projects
composer require coderden/image-optimizer
Usage
Basic Usage
// Create optimizer instance with default configuration $optimizer = new ImageOptimizer(); // Optimize a single image $result = $optimizer->optimize('/path/to/image.jpg'); // Get optimization results echo "Optimization successful: " . ($result->success ? 'Yes' : 'No') . "\n"; echo "Saved: " . $result->getSavedBytes() . " bytes\n"; echo "Compression: " . $result->getCompressionPercentage() . "%\n"; echo "Original size: " . $result->originalSize . " bytes\n"; echo "Optimized size: " . $result->optimizedSize . " bytes\n";
With Custom Options
$optimizer = new ImageOptimizer(); // Optimize with custom settings $result = $optimizer->optimize( '/path/to/image.jpg', '/path/to/output.jpg', // Optional destination path [ 'quality' => 75, 'stripAll' => true, 'progressive' => false ] ); // For PNG images $result = $optimizer->optimize( '/path/to/image.png', null, // Overwrite original [ 'optimizer' => 'optipng', 'quality' => 90, 'speed' => 5 ] );
Batch Optimization
$optimizer = new ImageOptimizer(); $results = $optimizer->batchOptimize([ '/path/to/image1.jpg', '/path/to/image2.png', '/path/to/image3.jpg', ]); foreach ($results as $result) { if ($result->success) { echo "Optimized {$result->sourcePath}: saved {$result->getSavedBytes()} bytes\n"; } else { echo "Failed to optimize {$result->sourcePath}: {$result->error}\n"; } }
Custom Configuration
$config = [ 'jpeg' => [ 'quality' => 70, 'progressive' => false, 'strip_all' => false, ], 'png' => [ 'optimizer' => 'optipng', 'quality' => 90, 'speed' => 1, // Slowest but best compression ], ]; $optimizer = new ImageOptimizer($config);
Directory Optimization
You can optimize entire directories recursively with a single command:
$optimizer = new ImageOptimizer(); // Optimize all images in a directory (recursive by default) $results = $optimizer->optimizeDirectory('/path/to/images'); // Optimize only files in the root directory (non-recursive) $results = $optimizer->optimizeDirectory('/path/to/images', false); // Optimize with custom options $results = $optimizer->optimizeDirectory('/path/to/images', true, [ 'quality' => 75, 'stripAll' => true ]); // Optimize only specific extensions $results = $optimizer->optimizeDirectory('/path/to/images', true, [], ['jpg', 'png']); // Don't overwrite original files (create optimized copies with .optimized suffix) $results = $optimizer->optimizeDirectory('/path/to/images', true, [], null, false); // Get directory statistics $stats = $optimizer->getDirectoryStats($results); echo "Total files processed: " . $stats['total_files'] . "\n"; echo "Successful: " . $stats['successful'] . "\n"; echo "Failed: " . $stats['failed'] . "\n"; echo "Total saved: " . $this->formatBytes($stats['total_saved_bytes']) . "\n"; echo "Average compression: " . round($stats['average_compression'], 2) . "%\n"; // Process individual results foreach ($results as $result) { if ($result->success) { echo "✓ " . basename($result->sourcePath) . ": "; echo "Saved " . $result->getFormattedSavedSize() . " "; echo "(" . round($result->getCompressionPercentage(), 2) . "%)\n"; } else { echo "✗ " . basename($result->sourcePath) . ": " . $result->error . "\n"; } }
Optimizers
JPEG Optimizer (jpegoptim)
- Quality: 0-100 (default: 85)
- Strip All: Remove all metadata (default: true)
- Progressive: Create progressive JPEGs (default: true)
PNG Optimizers
You can choose between three optimizers:
-
pngquant (default): Best for quality/size ratio
- Quality: 0-100 (default: 80)
- Speed: 1-10 (1=slow/best, 10=fast/good)
-
optipng: Lossless optimization
- Uses various optimization levels
-
pngcrush: Alternative lossless optimizer
Error Handling
The package throws OptimizationException when something goes wrong:
try { $optimizer = new ImageOptimizer(); $result = $optimizer->optimize('/path/to/image.jpg'); } catch (OptimizationException $e) { echo "Error: " . $e->getMessage() . "\n"; echo "Command: " . $e->getCommand() . "\n"; echo "Output: " . implode("\n", $e->getOutput()) . "\n"; }