guillaumetissier / image-resizer
PHP implementation of an image resizer.
Requires
- php: >=8.1
- ext-gd: *
- guillaumetissier/path-utilities: ^1.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.92
- phpunit/phpunit: ^10.5
README
A powerful and flexible PHP library for resizing images with configurable validation constraints.
Features
- ๐ฏ Simple API - Intuitive fluent interface for easy image manipulation
- โ๏ธ Configurable - Customizable validation constraints for width, height, ratio, and quality
- ๐ก๏ธ Secure - Pre-configured profiles for different security requirements
- ๐งช Well-tested - Comprehensive test coverage
- ๐ง Extensible - Clean architecture with dependency injection
- ๐ฆ Multiple formats - Support for JPEG, PNG, and GIF
Requirements
- PHP 8.1 or higher
- GD extension or Imagick extension
Installation
Install via Composer:
composer require guillaumetissier/image-resizer
Quick Start
use Guillaumetissier\ImageResizer\ImageResizer; use Guillaumetissier\ImageResizer\Constants\Transformations; use Guillaumetissier\ImageResizer\Constants\Options; // Create resizer with safe configuration $resizer = ImageResizer::create(); // Resize image $resizer ->setTransformation(Transformations::SET_RATIO, 0.8) ->setOption(Options::QUALITY, 85) ->resize('source.jpg', 'output.jpg');
Usage
Basic Resizing
use Guillaumetissier\ImageResizer\Constants\ResizeType; use Guillaumetissier\ImageResizer\ImageResizer; use Guillaumetissier\ImageResizer\Constants\Transformations; $resizer = ImageResizer::create(); // Resize by aspect ratio (default) $resizer ->setTransformation(Transformations::SET_RATIO, 2) ->resize('image.jpg', 'resized.jpg'); // Resize by width (maintains aspect ratio) $resizer ->setResizeType(ResizeType::FIXED_WIDTH) ->setTransformation(Transformations::SET_WIDTH, 800) ->resize('image.jpg', 'resized.jpg'); // Resize by height (maintains aspect ratio) $resizer ->setResizeType(ResizeType::FIXED_HEIGHT) ->setTransformation(Transformations::SET_HEIGHT, 600) ->resize('image.jpg', 'resized.jpg'); // Resize with fixed height and width $resizer ->setResizeType(ResizeType::FIXED) ->setTransformation(Transformations::SET_HEIGHT, 600) ->setTransformation(Transformations::SET_WIDTH, 300) ->resize('image.jpg', 'resized.jpg');
Multiple Transformations
$resizer->setTransformations([ Transformations::SET_WIDTH->value => 1920, Transformations::SET_HEIGHT->value => 1080, ]); $resizer->resize('source.jpg', 'output.jpg');
Quality and Options
use Guillaumetissier\ImageResizer\Constants\Options; $resizer = ImageResizer::create() ->setTransformation(Transformations::SET_RATIO, 0.5) ->setOption(Options::QUALITY, 85) // JPEG quality (0-100) ->setOption(Options::INTERLACE, true); // Progressive JPEG // Or set multiple options at once $resizer->setOptions([ Options::QUALITY->value => 90, Options::INTERLACE->value => true, ]); $resizer->resize('image.jpg', 'output.jpg');
Method Chaining
All setter methods return $this for fluent interface:
ImageResizer::create() ->setType(ResizeType::FIXED) ->setTransformation(Transformations::SET_WIDTH, 1920) ->setTransformation(Transformations::SET_HEIGHT, 1080) ->setOption(Options::QUALITY, 85) ->setOption(Options::INTERLACE, true) ->resize('input.jpg', 'output.jpg');
Configuration Profiles
ImageResizer comes with pre-configured validation profiles for different use cases.
Available Profiles
use Guillaumetissier\ImageResizer\ImageResizerConfig; // Default configuration $resizer = ImageResizer::create(ImageResizerConfig::default()); // Safe configuration - for public websites with user uploads $resizer = ImageResizer::create(ImageResizerConfig::safe()); // Strict configuration - for high-security environments $resizer = ImageResizer::create(ImageResizerConfig::strict()); // Thumbnail configuration - optimized for small images $resizer = ImageResizer::create(ImageResizerConfig::thumbnail()); // Web configuration - optimized for web display $resizer = ImageResizer::create(ImageResizerConfig::web()); // Print configuration - optimized for print quality $resizer = ImageResizer::create(ImageResizerConfig::print());
Profile Specifications
| Profile | Max Width | Max Height | Quality Range | Ratio Range | Use Case |
|---|---|---|---|---|---|
default() |
2000px | 2000px | 0-100 | 0.01-10.0 | Standard usage |
safe() |
8000px | 8000px | 50-95 | 0.1-2.0 | Public websites |
strict() |
4000px | 4000px | 60-90 | 0.5-1.0 | Secure environments |
thumbnail() |
500px | 500px | 70-85 | - | Thumbnails |
web() |
2000px | 2000px | 70-90 | - | Web images |
print() |
10000px | 10000px | 85-100 | - | Print quality |
Custom Configuration
Create your own configuration with specific constraints:
use Guillaumetissier\ImageResizer\ImageResizerConfig; $config = new ImageResizerConfig([ 'minWidth' => 100, // Minimum width in pixels 'maxWidth' => 3000, // Maximum width in pixels 'minHeight' => 100, // Minimum height in pixels 'maxHeight' => 3000, // Maximum height in pixels 'minRatio' => 0.5, // Minimum aspect ratio (width/height) 'maxRatio' => 2.0, // Maximum aspect ratio 'minQuality' => 60, // Minimum JPEG quality (0-100) 'maxQuality' => 95, // Maximum quality 'defaultQuality' => 85, // Default quality if not specified 'defaultInterlace' => true, // Enable progressive JPEG by default ]); $resizer = ImageResizer::create($config);
Validation
ImageResizer validates all inputs to ensure safe and consistent image processing.
Automatic Validation
All transformations and options are automatically validated:
try { $resizer = ImageResizer::create(ImageResizerConfig::safe()); // This will throw InvalidRangeException if width > 8000 $resizer->setTransformation(Transformations::SET_WIDTH, 10000); } catch (\Guillaumetissier\ImageResizer\Exceptions\InvalidRangeException $e) { echo "Validation error: " . $e->getMessage(); }
Common Exceptions
InvalidRangeException- Value is out of allowed rangeInvalidTypeException- Value has wrong typeInvalidPathException- File path is invalid or file doesn't exist
Validation Examples
use Guillaumetissier\ImageResizer\ImageResizerConfig; $config = ImageResizerConfig::strict(); // Max width: 4000px $resizer = ImageResizer::create($config)->setType(ResizeType::FIXED_WIDTH); // โ Valid - within limits $resizer->setTransformation(Transformations::SET_WIDTH, 2000); // โ Invalid - exceeds max width $resizer->setTransformation(Transformations::SET_WIDTH, 5000); // Throws: InvalidRangeException // โ Invalid - wrong type $resizer->setTransformation(Transformations::SET_WIDTH, "2000"); // Throws: InvalidTypeException // โ Invalid - file doesn't exist $resizer->resize('nonexistent.jpg', 'output.jpg'); // Throws: InvalidPathException
Examples
Example 1: User Avatar Processing
use Guillaumetissier\ImageResizer\Constants\ResizeType; use Guillaumetissier\ImageResizer\ImageResizer; use Guillaumetissier\ImageResizer\ImageResizerConfig; use Guillaumetissier\ImageResizer\Constants\Transformations; use Guillaumetissier\ImageResizer\Constants\Options; // Strict validation for user uploads $resizer = ImageResizer::create(ImageResizerConfig::strict()); try { $resizer ->setResizeType(ResizeType::FIXED) ->setTransformations([ Transformations::SET_WIDTH => 200, Transformations::SET_HEIGHT => 200, ]) ->setOptions([ Options::QUALITY => 85, Options::INTERLACE => true, ]) ->resize($_FILES['avatar']['tmp_name'], 'uploads/avatars/user-123.jpg'); echo "Avatar uploaded successfully!"; } catch (\Exception $e) { echo "Error: " . $e->getMessage(); }
Example 2: Batch Processing
$resizer = ImageResizer::create(ImageResizerConfig::web()) ->setType(ResizeType::FIXED_WIDTH) ->setTransformation(Transformations::SET_WIDTH, 1920) ->setOption(Options::QUALITY, 85); $images = glob('originals/*.jpg'); foreach ($images as $image) { $filename = basename($image); try { $resizer->resize($image, "processed/{$filename}"); echo "Processed: {$filename}\n"; } catch (\Exception $e) { echo "Error processing {$filename}: {$e->getMessage()}\n"; } }
Example 3: Creating Thumbnails
$resizer = ImageResizer::create(ImageResizerConfig::thumbnail()) ->setType(ResizeType::FIXED_HEIGHT) ->setOptions([ Options::QUALITY => 75, Options::INTERLACE => false, ]); // Create multiple thumbnail sizes $sizes = [ 'small' => 150, 'medium' => 300, 'large' => 500, ]; foreach ($sizes as $name => $height) { $resizer->setTransformation(Transformations::SET_HEIGHT, $height) ->resize('original.jpg', "thumbnails/{$name}.jpg"); }
Architecture
ImageResizer follows SOLID principles and uses dependency injection for flexibility:
ImageResizer (main class)
โโโ ValidatorFactory (creates validators with config)
โ โโโ WidthValidator
โ โโโ HeightValidator
โ โโโ RatioValidator
โ โโโ QualityValidator
โ โโโ ...
โโโ DimensionsReader (reads image dimensions)
โโโ DimensionCalculatorFactory (create resize-specific calculators)
โ โโโ FixedDimensionsCalculator
โ โโโ FixedHeightCalculator
โ โโโ FixedWidthCalculator
โ โโโ ProportionalDimensionsCalculator
โโโ ImageResizerFactory (creates format-specific resizers)
โโโ JpegImageResizer
โโโ PngImageResizer
โโโ GifImageResizer
API Reference
ImageResizer
Factory Method
public static function create(?ImageResizerConfig $config = null): self
Creates a new ImageResizer instance with optional configuration.
Methods
// Set a single transformation public function setTransformation(Transformations $transformation, mixed $value): self // Set multiple transformations at once public function setTransformations(array $transformations): self // Set a single option public function setOption(Options $option, int|bool|string $value): self // Set multiple options at once public function setOptions(array $options): self // Resize the image public function resize(string $source, ?string $target = null): void
ImageResizerConfig
Factory Methods
public static function default(): self public static function safe(): self public static function strict(): self public static function thumbnail(): self public static function web(): self public static function print(): self
Constructor
public function __construct(array $config = [])
Available parameters:
minWidth(int|null) - Minimum width in pixelsmaxWidth(int|null) - Maximum width in pixelsminHeight(int|null) - Minimum height in pixelsmaxHeight(int|null) - Maximum height in pixelsminRatio(float|null) - Minimum aspect ratiomaxRatio(float|null) - Maximum aspect ratiominQuality(int|null) - Minimum quality (0-100)maxQuality(int|null) - Maximum quality (0-100)defaultQuality(int) - Default quality valuedefaultInterlace(bool) - Default interlace setting
Constants
Transformations
Transformations::SET_WIDTH // Resize by width Transformations::SET_HEIGHT // Resize by height Transformations::SET_RATIO // Resize by aspect ratio
Options
Options::QUALITY // Image quality (0-100) Options::INTERLACE // Progressive/interlaced (bool) Options::SCALE_MODE // Scaling mode (integer)
Migration from v1.x
Breaking Changes
The constructor is now private. Use the factory method instead:
// โ v1.x - No longer works $resizer = new ImageResizer(...); // โ v2.0 - Use factory method $resizer = ImageResizer::create(); $resizer = ImageResizer::create(ImageResizerConfig::safe());
No Changes Needed
If you were already using ImageResizer::create(), no changes are required:
// This works in both v1.x and v2.0 $resizer = ImageResizer::create(); $resizer->setTransformation(Transformations::SET_WIDTH, 800); $resizer->resize('input.jpg', 'output.jpg');
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
- ๐ง Email: [guillaume.tissier@yahoo.com]
- ๐ Issues: GitHub Issues
- ๐ Documentation: Full Documentation
Changelog
See CHANGELOG.md for a detailed list of changes.
Credits
Created and maintained by Guillaume Tissier