Build image transform URLs for Small Pics in PHP.
- v1 to v2 upgrade guide
- PHP 8.1+
composer require smallpics/smallpics-php:^2.0.0Create an Options instance, configure the transform, then pass it with the image path to a UrlBuilder.
use smallpics\smallpics\Options;
use smallpics\smallpics\UrlBuilder;
$options = new Options();
$options
->setWidth(800)
->setHeight(600)
->setFit('crop')
->setQuality(80);
$builder = new UrlBuilder('https://images.example.com');
$url = $builder->buildUrl('bird.jpg', $options);
// https://images.example.com/bird.jpg?fit=crop&h=600&q=80&w=800The image path may include leading or trailing slashes; they are normalized when the URL is built.
Pass your Small Pics signing secret as the second argument to UrlBuilder. The signature is calculated from the normalized URL and added as s.
use smallpics\smallpics\Options;
use smallpics\smallpics\UrlBuilder;
$options = new Options([
'width' => 800,
'height' => 600,
]);
$builder = new UrlBuilder(
'https://images.example.com',
'0123456789abcdef0123456789abcdef',
);
$url = $builder->buildUrl('bird.jpg', $options);
// https://images.example.com/bird.jpg?h=600&w=800&s=...Do not commit signing secrets. Load them from your application's environment or secret manager.
Options is a fluent value object that serializes to Small Pics query parameters.
use smallpics\smallpics\Options;
$options = (new Options())
->setWidth(800)
->setHeight(600)
->setFit('crop')
->setCropPosition('top')
->setFormat('avif');
echo $options;
// w=800&h=600&fit=crop&crop=top&fm=avifThe constructor accepts setter names in camelCase and short query keys such as w, fp, and markpad.
use smallpics\smallpics\Options;
$options = new Options([
'width' => 800,
'height' => 600,
'fit' => 'crop',
'crop' => 'top',
'border' => [
// Expanded into named parameters for `setBorder`
'width' => 8,
'color' => 'ffffff',
'borderMethod' => 'expand',
],
]);
echo $options;
// w=800&h=600&fit=crop&crop=top&border=8,ffffff,expandFor a raw or future Small Pics query parameter, use setParam() or setParams().
$options->setParam('my-option', 'value');
$options->setParams([
'another-option' => 1,
'enabled' => true,
]);Boolean raw parameters are serialized as 1 or 0.
Setters that have a fixed set of values accept their matching enum as well as a string. Enums are in smallpics\smallpics\enums.
use smallpics\smallpics\Options;
use smallpics\smallpics\enums\Fit;
use smallpics\smallpics\enums\Format;
$options = (new Options())
->setFit(Fit::CROP)->setCropPosition('top')
->setFormat(Format::AVIF);Available enums are BorderMethod, Filter, Fit, Format, and WatermarkPosition.
Use fluent setters, constructor options, or setParam() for serialized query values. Refer to the Small Pics documentation for processing behavior and valid ranges.
| Query parameter | Setter | Accepted values | Example |
|---|---|---|---|
or |
setOrientation() |
0, 90, 180, 270, or auto |
->setOrientation('auto') |
flip |
setFlip() |
v, h, or both |
->setFlip('h') |
crop |
setCrop() / setCropPosition() |
Named anchor, face[,fallback], facesarea[,fallback], or width, height, x, y |
->setCrop(400, 300, 10, 20) |
w |
setWidth() |
Integer or decimal pixels, or relative dimensions | ->setWidth('65p') |
h |
setHeight() |
Integer or decimal pixels, or relative dimensions | ->setHeight('50w') |
ar |
setAspectRatio() |
width:height, decimal ratio, or dividend and divisor |
->setAspectRatio(16, 9) |
fit |
setFit() |
See Fit and Crop Position | ->setFit('crop')->setCropPosition('top') |
dpr |
setDevicePixelRatio() |
Integer or decimal | ->setDevicePixelRatio(1.5) |
bri |
setBrightness() |
Integer brightness | ->setBrightness(10) |
con |
setContrast() |
Integer contrast | ->setContrast(15) |
gam |
setGamma() |
Float gamma | ->setGamma(1.2) |
sharp |
setSharpen() |
Integer sharpen amount | ->setSharpen(20) |
blur |
setBlur() |
Integer blur amount | ->setBlur(5) |
pixel |
setPixelate() |
Integer pixelate amount | ->setPixelate(8) |
filt |
setFilter() |
grayscale or sepia |
->setFilter('grayscale') |
mark |
setWatermarkPath() |
Watermark image path | ->setWatermarkPath('/watermark.png') |
markorigin |
setWatermarkOrigin() |
Watermark origin name | ->setWatermarkOrigin('default') |
markw |
setWatermarkWidth() |
Integer, decimal, or relative width | ->setWatermarkWidth('20w') |
markh |
setWatermarkHeight() |
Integer, decimal, or relative height | ->setWatermarkHeight('20h') |
markfit |
setWatermarkFit() |
See Fit and Crop Position | ->setWatermarkFit('contain') |
markfp |
setWatermarkFocalPoint() |
Pixels, relative values, or x:y within the watermark |
->setWatermarkFocalPoint('20p', '20p') |
markzoom |
setWatermarkZoom() |
Numeric zoom from 1 to 100 |
->setWatermarkZoom(2) |
markpad |
setWatermarkPadding() |
Pixels, relative values, or x:y |
->setWatermarkPadding(16) |
markpos |
setWatermarkPosition() |
Named anchor, numeric coordinate, or pixel/relative x:y string |
->setWatermarkPosition('bottom-right') |
markalpha |
setWatermarkAlpha() |
Integer alpha | ->setWatermarkAlpha(80) |
bg |
setBackground() |
Background color | ->setBackground('ffffff') |
border |
setBorder() |
Width, color, and method | ->setBorder(8, 'ffffff', 'expand') |
q |
setQuality() |
Integer quality | ->setQuality(80) |
fm |
setFormat() |
See Output Format | ->setFormat('avif') |
interlace |
setInterlaced() |
Boolean | ->setInterlaced(true) |
fp |
setFocalPoint() |
Pixels or relative x/y | ->setFocalPoint('25w', '75h') |
zoom |
setZoom() |
Numeric, face, facesarea, optional numeric fallback |
->setZoom('face', 2.5) |
zoompad |
setZoomPadding() |
Pixels or relative x/y | ->setZoomPadding(10, 20) |
face |
setFace() |
One-based face index | ->setFace(1) |
debug |
setDebug() |
Boolean | ->setDebug(true) |
passthrough |
setPassthrough() |
Boolean; false removes the flag | ->setPassthrough(true) |
Dimensions accept decimal pixels and p, w, or h percentage units. For example, 5w means 5% of the base image's width, and 35h means 35% of its height. Paired values accept serialized x:y strings.
setFit() and setWatermarkFit() accept contain, max, fill, fill-max, stretch, and crop.
Use setCropPosition('top') or constructor ['crop' => 'top'] for a named crop. Anchors are top-left, top, top-right, left, center, right, bottom-left, bottom, and bottom-right.
$options->setFit('crop')->setCropPosition('top');
// fit=crop&crop=top
$options->setFocalPoint('25w', '75h')->setZoom(2.5);
// Adds fp=25w:75h&zoom=2.5An 80×80 watermark, zoomed 2× around 20p:20p and centered:
$options = (new Options())
->setWatermarkPath('bird.jpg')
->setWatermarkWidth(80)
->setWatermarkHeight(80)
->setWatermarkFit('crop')
->setWatermarkFocalPoint('20p', '20p')
->setWatermarkZoom(2)
->setWatermarkPosition('center');$options = (new Options())
->setFit('crop')
->setCropPosition('face,top')
->setFace(1)
->setZoom('face', 2.5)
->setZoomPadding('5p', '10p')
->setDebug(true);
// fit=crop&crop=face,top&face=1&zoom=face,2.5&zoompad=5p:10p&debug=1Image dimensions, focal points, watermark dimensions, positioning, padding, and border width accept relative values. p uses the relevant axis, so 25p means 25% of width for x and 25% of height for y. Append w or h to a percentage between 0 and 100: 5w is 5% of the source width and 35h is 35% of the source height.
$options
->setWatermarkWidth('20w')
->setWatermarkPadding('5w')
->setBorder('2w', 'ffffff', 'overlay');Setters accept current values directly and keep existing numeric calls working:
$options = (new Options())
->setWidth('65p')
->setHeight('50w')
->setDevicePixelRatio(1.5)
->setAspectRatio('16:9');
$width = $options->getWidth(); // '65p'Dimension and padding getters preserve numeric and relative values. getWatermarkPosition() returns an enum for named positions or the coordinate value. getAspectRatio() returns the numeric ratio.
setFormat() accepts jpg, jpeg, pjpg, png, gif, webp, avif, jxl. The alias jpeg normalizes to jpg.
Unless a specific output format is required, omit fm. Small Pics can select a format from the request's Accept header. If neither a format nor an Accept header is present, Small Pics defaults to AVIF. GIF images default to WebP, which supports animation.
$options->setFormat('jpeg');
echo $options; // fm=jpgSet passthrough: true in transform parameters (PHP: ['passthrough' => true]) to serve the original SVG through Small Pics, ignoring transforms. Other image formats still transform normally. Set it to false to omit the flag.
The fluent helper is $options->setPassthrough(), with getPassthrough() to check it. The service checks presence, so raw setParam('passthrough', false) still enables passthrough; use setPassthrough(false) to disable it.
$options = (new Options())->setPassthrough(true);
$url = (new UrlBuilder('https://images.example.com'))->buildUrl('logo.svg', $options);
// https://images.example.com/logo.svg?passthrough=1
$options->setPassthrough(false); // Removes passthrough from the URL.Install development dependencies:
composer installRun the test suite:
composer testRun static analysis and style checks:
composer phpstan
composer ecs:check
composer rector:dry-runApply style fixes:
composer ecs:fix