ImageStack
A PHP image serving framework., (*1)
The main goal is to provide a robust framework to create an "on the fly" image thumbnailer generator similar to imagecache / image style in Drupal., (*2)
This project is only the framework part. The framework is brick designed so that you can put together your own image serving project and add special bricks., (*3)
Framework integration:
Installation
composer require quazardous/imagestack
Concept
Typical flow
This describes the typical processing we want to achieve., (*4)
When the front controller handles an image HTTP request:, (*5)
- the front controller will call image stack with the image path.
- the image stack will fetch the image using the image backend.
- the image stack will apply image manipulator.
- the image stack will store the image using the storage backend.
- the image stack will return the image to the front controller.
- the front controller will serve the image.
Ideally the image file will be stored so that the next HTTP request will be statically served., (*6)
Lexicon / bricks
Image path
The path of the image that could come from the front controller., (*7)
See ImageStack\Api\ImagePathInterface
., (*8)
Image
The image content we are willing to serve., (*9)
See ImageStack\Api\ImageInterface
., (*10)
Image backend
Something that can provide image content., (*11)
See ImageStack\Api\ImageBackendInterface
., (*12)
Image manipulator
Service that can modify/transform/optimize the image content., (*13)
See ImageStack\Api\ImageManipulatorInterface
., (*14)
Storage backend
Something where we can store the image content.
Typically we could store it onto the file system so that next HTTP query will be statically serve., (*15)
See ImageStack\Api\StorageBackendInterface
., (*16)
Image stack
Top of the iceberg class., (*17)
See ImageStack\Api\ImageStackInterface
., (*18)
Usage
Code example
This pseudo controller creates an image stack that will:
- fetch image from https://images.example.com/backend/
+ $path
- optimize it with jpegtran
- store it on '/var/www/my/local/image/storage/'
+ $path
- serve it, (*19)
function myImageController($path)
{
$stack = new \ImageStack\ImageStack(
new \ImageStack\ImageBackend\HttpImageBackend('https://images.example.com/backend/'),
new \ImageStack\StorageBackend\FileStorageBackend('/var/www/my/local/image/storage/'));
$oim = new \ImageStack\ImageManipulator\OptimizerImageManipulator();
$oim->registerImageOptimizer(new \ImageStack\ImageOptimizer\JpegtranImageOptimizer());
$stack->addImageManipulator($oim);
$image = $stack->stackImage(new \ImageStack\ImagePath($path));
return $image->getBinaryContent();
}
Implementation
Image stack
A basic image stack., (*20)
See ImageStack\ImageStack
, (*21)
Image backends
File image backend
See ImageStack\ImageBackend\FileImageBackend
, (*22)
HTTP image backend
See ImageStack\ImageBackend\HttpImageBackend
, (*23)
Cache image backend
Add a cache layer before an image backend., (*24)
See ImageStack\ImageBackend\CacheImageBackend
, (*25)
Sequential image backend
Sequentially fetch image from a queue of image backends and return the first match., (*26)
See ImageStack\ImageBackend\SequentialImageBackend
, (*27)
Image manipulators
Converter image manipulator
Convert image type., (*28)
See ImageStack\ImageManipulator\ConverterImageManipulator
, (*29)
Optimizer image manipulator
Optimize image., (*30)
See ImageStack\ImageManipulator\OptimizerImageManipulator
, (*31)
jpegtran
wrapper, see ImageStack\ImageOptimizer\JpegtranImageOptimizer
., (*32)
pngcrush
wrapper, see ImageStack\ImageOptimizer\PngcrushImageOptimizer
., (*33)
Thumbnailer image manipulator
Create an image thumbnail with (path) rules., (*34)
See ImageStack\ImageManipulator\ThumbnailerImageManipulator
, (*35)
Path pattern rule, see ImageStack\ImageManipulator\ThumbnailRule\PatternThumbnailRule
, (*36)
You can associate path patterns to thumbnail formats:, (*37)
use ImageStack\ImageManipulator\ThumbnailerImageManipulator;
use Imagine\Gd\Imagine;
use ImageStack\ImagePath;
use ImageStack\ImageManipulator\ThumbnailRule\PatternThumbnailRule;
...
$rules = [
'|^images/styles/big/|' => '<500x300', // resize to fit in 500x300 box
'|^images/styles/box/|' => '200x200', // resize/crop to 200x200 box
'|^images/styles/list/|' => '100', // resize/crop to 100x100 box
'|^images/([0-9]+)x([0-9]+)/|' => function ($matches) { return "{$matches[1]}x{$matches[2]}"; }, // custom resize/crop
'|.*|' => false, // trigger an image not found exception if nothing matches
];
$tim = new ThumbnailerImageManipulator(new Imagine());
foreach ($rules as $pattern => $format) {
$tim->addThumbnailRule(new PatternThumbnailRule($pattern, $format));
}
// this will resize the given image to fit in a 500x300 box
$tim->manipulateImage($image, new ImagePath('images/styles/big/photo.jpg'));
// this will resize/crop the given image to a 200x200 box
$tim->manipulateImage($image, new ImagePath('images/200x150/photo.jpg'));
// this will rise a 404
$tim->manipulateImage($image, new ImagePath('bad/path/photo.jpg'));
Watermark image manipulator
Add watermark to images., (*38)
See ImageStack\ImageManipulator\WatermarkImageManipulator
, (*39)
use ImageStack\ImageManipulator\WatermarkImageManipulator;
use Imagine\Gd\Imagine;
use ImageStack\ImagePath;
...
// repeat the watermark
$wim = new WatermarkImageManipulator(new Imagine(), '/path/to/little-watermark.png', [
'repeat' => WatermarkImageManipulator::REPEAT_ALL,
]);
$wim->manipulateImage($image, new ImagePath('protected_image.jpg'));
// reduce and anchor a big the watermark
$wim = new WatermarkImageManipulator(new Imagine(), '/path/to/huge-watermark.png', [
'reduce' => WatermarkImageManipulator::REDUCE_INSET,
'anchor' => WatermarkImageManipulator::ANCHOR_BOTTOM|WatermarkImageManipulator::ANCHOR_RIGHT,
]);
$wim->manipulateImage($image, new ImagePath('protected_image.jpg'));
Tests
git clone git@github.com:quazardous/ImageStack.git
cd ./ImageStack
cp tests/config-dist.php tests/config.php
Edit/adapt tests/config.php
., (*40)
composer.phar update -dev
phpunit.phar
Dependencies / support
Tested against PHP 7.1., (*41)
Current implementation uses Imagine., (*42)
You will need either php-gd
, php-gmagick
or php-imagick
., (*43)
Wrappers for external optimizer:
- jpegtran
- pngcrush
- gifsicle, (*44)
History
- 1.5: add animated GIFs support in thumbnail and watermark (Imagick only)
- 1.4: add optimize gifsicle
- 1.3: allow backend to have image manipulator
- 1.2: add watermark
- 1.1: add path rules
- 1.0: current version
- 0.9: pre version mainly a raw copy/paste from an old project
Credits
quazardous., (*45)
License
MIT, (*46)