Resize, crop and encode images from PHP with lazy execution, predictable output geometry and one decode for multiple derivatives.
Image represents one source and one requested output. ImageSet represents
several outputs from that source and renders them together. Both are immutable
and hold no decoded pixels.
Header inspection, projected dimensions, signatures and derivative paths need no image extension. Rendering uses GD or Imagick.
- Crop by coordinates, anchor, focal point, attention or entropy.
- Preserve ICC profiles or convert pixels to another colour space with Imagick.
- Produce several sizes and formats from one source decode.
- Read files, encoded bytes and streams. Write files or storage backends.
- Encode common raster formats supported by the selected driver. Controls include quality, effort, byte limits, progressive output and lossless output.
- Extract dominant colours and compare images with perceptual hashes.
See crop, colour profile conversion, encoding and analysis.
Install ALTO Image with Composer:
composer require alto/imageALTO Image requires PHP 8.3 or later. Rendering requires ext-gd or ext-imagick.
Inspect the available formats and local extension configuration with:
vendor/bin/image doctoruse Alto\Image\Image;
Image::open('photo.jpg')
->cover(800, 450)
->webp(80)
->save('hero.webp');Drivers are detected automatically and safe input limits are applied before decoding.
Composer installs vendor/bin/image with three subcommands:
| Command | Purpose |
|---|---|
image doctor |
Inspect installed drivers and formats |
image info |
Read image headers without decoding |
image convert |
Transform and write one image |
Run them through vendor/bin/image. See the
command-line reference for arguments, examples and exit
codes.
Create a responsive image set and write it to a local derivative store:
use Alto\Image\Format;
use Alto\Image\Image;
$results = Image::open('photo.jpg')
->cover(ratio: 16 / 9)
->widths(640, 960, 1280)
->formats(Format::Webp, Format::Avif)
->store('public/media');The resulting ImageSet contains six images in the requested order. Missing
outputs are rendered together with one source decode.
Combine outputs with different shapes or qualities using and():
use Alto\Image\Image;
$source = Image::open('upload.jpg');
$results = $source->cover(1600, 900)->webp(82)
->and($source->cover(600, 400)->webp(80))
->and($source->cover(160, 160)->webp(75))
->store('public/media');Named methods cover common geometry and encoding operations:
use Alto\Image\Image;
$image = Image::open('photo.jpg')
->fit(1600, 1600)
->sharpen()
->webp(80);
$size = $image->size();
$key = $image->signature();
$result = $image->render();Transforms can also be parsed from their stable string representation:
use Alto\Image\Image;
use Alto\Image\Transform;
$transform = Transform::parse('cover=1280x720,g:top-right|sharpen');
$result = Image::open('photo.jpg')
->transformedBy($transform)
->webp()
->render();Pass a directory directly for local storage, or use a store object when the application needs paths, pruning or another backend:
use Alto\Image\Image;
use Alto\Image\Store\LocalStore;
$store = new LocalStore('public/media');
$image = Image::open('photo.jpg')->cover(800, 450)->webp();
$path = $store->path($image);
$result = $image->store($store);
$removed = $store->prune(new DateTimeImmutable('-30 days'));FlysystemStore supports Flysystem adapters. Custom stores implement
Store\StoreInterface.
Metadata is stripped by default, including EXIF and GPS data. Request only the
ICC profile with keepColourProfile(), or all supported metadata with
keepMetadata().
use Alto\Image\Image;
use Alto\Image\Limits;
Image::open($upload)
->within(new Limits(maxPixels: 20_000_000))
->fit(1600, 1600)
->webp()
->save($destination);Read SECURITY.md before processing untrusted paths or transform strings. Limit user-supplied transformations to the operations the endpoint needs:
use Alto\Image\Transform;
$transform = Transform::parse(
$value,
only: ['cover', 'crop', 'sharpen'],
);- Documentation index
- Getting started
- Transformations
- Image sets
- Encoding
- Analysis
- Storage
- Metadata and safety
- Command line
- Public API
- Drivers
Contributions of all kinds are welcome. Visit the project on GitHub to report a bug, suggest a feature, or open a pull request.
Before submitting code, run:
# Runs PHP CS Fixer, PHPStan, and PHPUnit
composer qa
# Runs PHPUnit and enforces 100% line coverage
composer coverageChanges to public behavior should include tests and documentation. See CONTRIBUTING.md for package-specific guidance.
ALTO Image is open source. You can support its continued development through GitHub Sponsors.
Sharing this package with others or starring it on GitHub is also much appreciated.
ALTO Image is released by ALTO PHP under the MIT License.