PHPackages                             smallpics/craft-smallpics - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. smallpics/craft-smallpics

ActiveCraft-plugin

smallpics/craft-smallpics
=========================

Small Pics image transformer for Craft

1.3.0(2w ago)0327↑1191.7%MITPHPPHP ^8.1CI passing

Since Jul 16Pushed 2w agoCompare

[ Source](https://github.com/SmallPics/craft-smallpics)[ Packagist](https://packagist.org/packages/smallpics/craft-smallpics)[ RSS](/packages/smallpics-craft-smallpics/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (4)Dependencies (5)Versions (5)Used By (0)

[![header.svg](assets/header.svg)](assets/header.svg)

Small Pics for Craft CMS
========================

[](#small-pics-for-craft-cms)

Add [Small Pics](https://www.smallpics.io) image CDN and transforms to Craft CMS.

Requirements
------------

[](#requirements)

- Craft CMS 4.5+ or 5.0+
- PHP 8.1+

Installation
------------

[](#installation)

```
composer require smallpics/craft-smallpics
./craft plugin/install smallpics
```

or with DDEV

```
ddev composer require smallpics/craft-smallpics
ddev craft plugin/install smallpics
```

Configuration
-------------

[](#configuration)

Create `config/smallpics.php` in the root of your project, or copy and rename [config.php](src/config.php).

A source `baseUrl` is required.

### Configuration parameters

[](#configuration-parameters)

ParameterTypeRequiredDefaultDescription`transformNativeImages`BooleanNo`true`Use Small Pics for Craft's native image transforms.`transformThumbnails`BooleanNo`true`Use Small Pics for Craft thumbnail URLs.`thumbnailParams`ArrayNo`[]`Transform parameters applied to thumbnails after global and source defaults.`nativeTransformsParams`ArrayNo`[]`Transform parameters applied to native Craft transforms after global and source defaults.`defaultSource`StringNo`'default'`Source to use when a transform does not specify one. If omitted when `sources` is set, the first source is the default.`baseUrl`StringYes*None*Small Pics base URL for the default single source. **Required when `sources` is empty.**`secret`String or `null`No`null`Signing secret for the default single source. **Required if signed requests are enabled for your image source in Small Pics.**`transformSvgs`BooleanNo`false`Transform SVGs for the default single source.`transformAnimatedGifs`BooleanNo`true`Transform animated GIFs for the default single source.`sources`ArrayNo`[]`See [Source configuration](#source-configuration).`defaultParams`ArrayNo`[]`Transform parameters applied to every request before source and per-transform parameters.### Source configuration

[](#source-configuration)

ParameterTypeRequiredDefaultDescription`baseUrl`StringYes*None*Small Pics base URL for this source.`secret`String or `null`No`null`Signing secret for this source. Required if signed requests are enabled for your image source in Small Pics.`transformSvgs`BooleanNo`false`Transform SVGs for this source.`transformAnimatedGifs`BooleanNo`true`Transform animated GIFs for this source.`defaultParams`ArrayNo`[]`Transform parameters applied after global defaults and before per-transform parameters.### Single Source

[](#single-source)

```
return [
    'transformNativeImages' => true,
    'nativeTransformsParams' => [
        'q' => 55,
    ],
    'transformThumbnails' => true,
    'thumbnailParams' => [
        'q' => 50,
    ],
    'baseUrl' => 'https://my-source.smallpics.io',
    'secret' => getenv('SMALLPICS_SECRET') ?: null,
    'transformSvgs' => false,
    'transformAnimatedGifs' => false,
    'defaultParams' => [
        'q' => 65,
    ],
];
```

### Multiple Sources

[](#multiple-sources)

Use source labels to select the source setup for an image. The label is only used by the plugin and is not added to generated URLs.

See an example of selecting a source in the [Twig section](#select-a-source) below.

```
return [
    'transformNativeImages' => true,
    'nativeTransformsParams' => [
        'q' => 55,
    ],
    'transformThumbnails' => true,
    'thumbnailParams' => [
        'q' => 50,
    ],
    'defaultSource' => 'productImages',
    'sources' => [
        'productImages' => [
            'baseUrl' => getenv('SMALLPICS_PRODUCTS_BASE_URL'),
            'secret' => getenv('SMALLPICS_PRODUCTS_SECRET') ?: null,
            'transformSvgs' => false,
            'transformAnimatedGifs' => false,
            'defaultParams' => [
                'q' => 80,
            ],
        ],
        'editorialImages' => [
            'baseUrl' => getenv('SMALLPICS_EDITORIAL_BASE_URL'),
            'secret' => getenv('SMALLPICS_EDITORIAL_SECRET') ?: null,
            'transformSvgs' => false,
            'transformAnimatedGifs' => false,
        ],
    ],
];
```

### Parameter Precedence

[](#parameter-precedence)

Later values override earlier values.

- Direct calls: global `defaultParams`, source `defaultParams`, then the params passed to `transformImage()` or `srcset()`.
- Native Craft transforms: global `defaultParams`, source `defaultParams`, the Craft transform config, then `nativeTransformsParams`.
- Thumbnails: global `defaultParams`, source `defaultParams`, the generated thumbnail dimensions and mode, then `thumbnailParams`.

Native Craft Transforms
-----------------------

[](#native-craft-transforms)

Native Craft image transforms are handled automatically when `transformNativeImages` is enabled. Use `nativeTransformsParams` to set Small Pics params specifically for native transforms.

For example, to give all native transforms a lower quality than the default:

```
return [
    'transformNativeImages' => true,
    'nativeTransformsParams' => [
        'q' => 55, // Give all native transforms a lower quality.
    ],
    // ...
];
```

Native transforms are any transform applied to images automatically by Craft, or through native Craft operations. For example:

```
{{ asset.getUrl({ width: 800, height: 600, mode: 'crop' }) }}
{{ asset.getImg('hero') }}
{{ asset.getSrcset(['400w', '800w'], { width: 800 }) }}
```

Image thumbnails can also be handled automatically when `transformThumbnails` is enabled. Use `thumbnailParams` to override your Small Pics global defaults specifically for thumbnails.

```
return [
    'transformThumbnails' => true,
    'thumbnailParams' => [
        'q' => 50, // Give thumbnails the lowest quality.
    ],
    // ...
];
```

### Native Transform Key Mapping

[](#native-transform-key-mapping)

Craft transform keys are translated to Small Pics keys when native transforms are intercepted:

Craft keySmall Pics param`width``w``height``h``quality``q``mode``fit``position`cover position in `fit``fill``bg`Twig
----

[](#twig)

### Transform an Image

[](#transform-an-image)

`transformImage()` returns a `TransformedImage`. The image URL can be retrieved by either calling `getUrl()` or simply rendering the image instance as a string.

```
{% set image = craft.smallpics.transformImage(asset, {
    w: 800,
    h: 600,
    fit: 'cover',
    q: 80
}) %}

```

Both variations render:

```

```

#### Use a Named Transform

[](#use-a-named-transform)

You can also pass a named Craft transform handle as the config.

```

```

Renders:

```

```

#### Select a Source

[](#select-a-source)

Select a source with `source`.

```
{{ craft.smallpics.transformImage(asset, {
    source: 'editorialImages',
    w: 1200
}) }}
```

Assuming a baseUrl of `https://editorial-images.smallpics.io`, that would render:

```
https://editorial-images.smallpics.io/bird.jpg?w=1200
```

#### Set an Output Format

[](#set-an-output-format)

For format selection, see the note in [Transform Options](#transform-options).[1](#user-content-fn-format-selection-974927f853a57441f5211783d29ca9ae)

```

```

Renders:

```

```

### Create a Srcset

[](#create-a-srcset)

`srcset()` takes the image, descriptors, and common config.

```

```

Renders:

```

```

#### Set a Fallback `src`

[](#set-a-fallback-src)

If you need a fallback `src` value, you can reuse one of the transformed images from the generated srcset instead of creating a separate transform.

```
{% set srcset = craft.smallpics.srcset(
    asset,
    {
        '1x': { dpr: 1 },
        '2x': { dpr: 2 },
        '800w': { w: 800 }
    },
    {
        w: 400,
        h: 300,
        fit: 'cover'
    }
) %}

```

Renders:

```

```

#### Access Srcset Images

[](#access-srcset-images)

The `srcset` result can be accessed like an array. Use the same descriptor keys you passed to `srcset()`, such as `800w`, `1x`, or `2x`. Each item is a `TransformedImage`, so it can be cast to a string or used via `getUrl()` when you only need the URL.

Transform Options
-----------------

[](#transform-options)

All the transform options supported by the Small Pics transform API are supported by this plugin. Take a look at the [Small Pics docs](https://www.smallpics.io/docs/) for more detailed information about each parameter.

Transform options can use either the Small Pics URL param key or the option name used by `smallpics/smallpics-php`. For example, `q` and `quality` are equivalent.

The examples below use PHP array syntax. Use the equivalent object or array syntax in Twig templates.

Use a single value for options that accept a single argument:

```
[
    'w' => 800,
    'q' => 80,
]
```

Use an array for options that accept multiple arguments:

```
[
    'crop' => [400, 300, 10, 20],
    'ar' => [16, 9],
    'border' => [8, 'ffffff', 'pad'],
    'fit' => ['cover', 'cover-top'],
]
```

Query parameterPlugin option nameValueExampleSetter`or``orientation``0`, `90`, `180`, `270`, or `auto``'or' => 'auto'``setOrientation(int|string $orientation)``flip``flip``v`, `h`, or `both``'flip' => 'h'``setFlip(string $flip)``crop``crop``[width, height, x, y]``'crop' => [400, 300, 10, 20]``setCrop(int $width, int $height, int $x, int $y)``w``width`Integer width`'w' => 800``setWidth(int $width)``h``height`Integer height`'h' => 600``setHeight(int $height)``ar``aspectRatio`Ratio number, or `[dividend, divisor]``ar: 4 / 3`, `ar: 1.778`, or `'ar' => [16, 9]``setAspectRatio(int|float $dividend, null|int|float $divisor = null)``fit`[2](#user-content-fn-focal-point-crops-974927f853a57441f5211783d29ca9ae)`fit``contain`, `max`, `fill`, `fill-max`, `stretch`, `cover`, or `crop`; cover crop positions: `cover-top-left`, `cover-top`, `cover-top-right`, `cover-left`, `cover-center`, `cover-right`, `cover-bottom-left`, `cover-bottom`, or `cover-bottom-right`; or `[fit, cropPosition, focalPointX, focalPointY, zoom]``'fit' => ['cover', 'cover-top']``setFit(string|Fit $fit, null|string|CropPosition $cropPosition = null, ?int $focalPointX = null, ?int $focalPointY = null, ?int $zoom = null)``dpr``devicePixelRatio`Integer device pixel ratio`'dpr' => 2``setDevicePixelRatio(int $devicePixelRatio = 1)``bri``brightness`Integer brightness`'bri' => 10``setBrightness(int $brightness)``con``contrast`Integer contrast`'con' => 15``setContrast(int $contrast)``gam``gamma`Float gamma`'gam' => 1.2``setGamma(float $gamma)``sharp``sharpen`Integer sharpen amount`'sharp' => 20``setSharpen(int $sharpen)``blur``blur`Integer blur amount`'blur' => 5``setBlur(int $blur)``pixel``pixelate`Integer pixelate amount`'pixel' => 8``setPixelate(int $pixelate)``filt``filter``grayscale` or `sepia``'filt' => 'grayscale'``setFilter(string|Filter $filter)``mark``watermarkPath`Watermark image path`'mark' => '/watermark.png'``setWatermarkPath(string $watermarkPath)``markorigin``watermarkOrigin`Watermark origin name`'markorigin' => 'default'``setWatermarkOrigin(string $watermarkOrigin)``markw``watermarkWidth`Integer width or relative width string [3](#user-content-fn-relative-values-974927f853a57441f5211783d29ca9ae)`'markw' => 120``setWatermarkWidth(int|string $watermarkWidth)``markh``watermarkHeight`Integer height or relative height string [3](#user-content-fn-relative-values-974927f853a57441f5211783d29ca9ae)`'markh' => 80``setWatermarkHeight(int|string $watermarkHeight)``markfit`[2](#user-content-fn-focal-point-crops-974927f853a57441f5211783d29ca9ae)`watermarkFit``contain`, `max`, `fill`, `fill-max`, `stretch`, `cover`, or `crop`; cover crop positions: `cover-top-left`, `cover-top`, `cover-top-right`, `cover-left`, `cover-center`, `cover-right`, `cover-bottom-left`, `cover-bottom`, or `cover-bottom-right`; or `[fit, cropPosition, focalPointX, focalPointY, zoom]``'markfit' => 'contain'``setWatermarkFit(string|Fit $fit, null|string|CropPosition $cropPosition = null, ?int $focalPointX = null, ?int $focalPointY = null, ?int $zoom = null)``markx``watermarkXOffset`Integer offset or relative offset string [3](#user-content-fn-relative-values-974927f853a57441f5211783d29ca9ae)`'markx' => 20``setWatermarkXOffset(int|string $watermarkXOffset)``marky``watermarkYOffset`Integer offset or relative offset string [3](#user-content-fn-relative-values-974927f853a57441f5211783d29ca9ae)`'marky' => 20``setWatermarkYOffset(int|string $watermarkYOffset)``markpad``watermarkPadding`Integer padding or relative padding string [3](#user-content-fn-relative-values-974927f853a57441f5211783d29ca9ae)`'markpad' => 16``setWatermarkPadding(int|string $watermarkPadding)``markpos``watermarkPosition``top-left`, `top`, `top-right`, `left`, `center`, `right`, `bottom-left`, `bottom`, or `bottom-right``'markpos' => 'bottom-right'``setWatermarkPosition(string|WatermarkPosition $watermarkPosition)``markalpha``watermarkAlpha`Integer alpha`'markalpha' => 80``setWatermarkAlpha(int $watermarkAlpha)``bg``background`Background color string`'bg' => 'ffffff'``setBackground(string $background)``border``border``[width, color, method]`, where method is `overlay`, `shrink`, or `pad``'border' => [8, 'ffffff', 'pad']``setBorder(int|string $width, string $color, string|BorderMethod $borderMethod)``q``quality`Integer quality`'q' => 80``setQuality(int $quality)``fm`[1](#user-content-fn-format-selection-974927f853a57441f5211783d29ca9ae)`format``jpg`, `pjpg`, `png`, `gif`, `webp`, `avif`, or `jxl``'fm' => 'gif'``setFormat(string|Format $format)``interlace``interlaced`Boolean`'interlace' => true``setInterlaced(bool $interlaced)`PHP
---

[](#php)

```
use smallpics\craft\Plugin;

$image = Plugin::$instance->transformer->transformImage(
    $asset,
    [
        'w' => 800,
        'h' => 600,
    ]
);

$url = (string) $image; // 'https://my-source.smallpics.io/bird.jpg?h=600&w=800'
```

```
$srcset = Plugin::$instance->transformer->srcset(
    $asset,
    [
        '1x' => ['dpr' => 1],
        '2x' => ['dpr' => 2],
    ],
    [
        'w' => 400,
        'h' => 300,
        'fit' => 'cover',
    ]
);

$srcsetValue = (string) $srcset;
// 'https://my-source.smallpics.io/bird.jpg?dpr=1&fit=cover-center&h=300&w=400 1x, https://my-source.smallpics.io/bird.jpg?dpr=2&fit=cover-center&h=300&w=400 2x'
```

Reference
---------

[](#reference)

### TransformedImage

[](#transformedimage)

`transformImage()` returns a `smallpics\craft\models\TransformedImage`.

```
use smallpics\craft\Plugin;
use smallpics\craft\models\TransformedImage;

/** @var TransformedImage $image */
$image = Plugin::$instance->transformer->transformImage($asset, [
    'w' => 800,
    'h' => 600,
    'fit' => 'cover',
]);

$url = (string) $image; // 'https://my-source.smallpics.io/bird.jpg?fit=cover-center&h=600&w=800'
$url = $image->getUrl(); // 'https://my-source.smallpics.io/bird.jpg?fit=cover-center&h=600&w=800'
$width = $image->getWidth(); // 800
$height = $image->getHeight(); // 600
$mimeType = $image->getMimeType(); // 'image/jpeg'
$sourceAsset = $image->getSource(); // The original Craft asset.
$config = $image->getConfig(); // ['w' => 800, 'h' => 600, 'fit' => 'cover']
$options = $image->getOptions(); // The Small Pics Options object.
```

### TransformedSrcset

[](#transformedsrcset)

`srcset()` returns a `smallpics\craft\models\TransformedSrcset`.

This model is read-only.

```
use smallpics\craft\Plugin;
use smallpics\craft\models\TransformedImage;
use smallpics\craft\models\TransformedSrcset;

/** @var TransformedSrcset $srcset */
$srcset = Plugin::$instance->transformer->srcset(
    $asset,
    [
        '400w' => ['w' => 400],
        '800w' => ['w' => 800],
    ],
    [
        'h' => 300,
        'fit' => 'cover',
    ]
);

$srcsetValue = (string) $srcset;
// 'https://my-source.smallpics.io/bird.jpg?fit=cover-center&h=300&w=400 400w, https://my-source.smallpics.io/bird.jpg?fit=cover-center&h=300&w=800 800w'

/** @var TransformedImage $smallImage */
$smallImage = $srcset['400w']; // The transformed 400px-wide image.
$smallImageUrl = (string) $smallImage; // 'https://my-source.smallpics.io/bird.jpg?fit=cover-center&h=300&w=400'

foreach ($srcset as $descriptor => $image) {
    $url = $image->getUrl(); // 'https://my-source.smallpics.io/bird.jpg?fit=cover-center&h=300&w=400' for '400w'.
}
```

Footnotes
---------

1. **Format selection.** Unless you specifically need a format, omit `fm` or `format` from transforms. Small Pics uses the request's `Accept` header to choose the output format when one is present. If you set `fm` but the requested format is not accepted by the `Accept` header, Small Pics uses the header to choose the format instead. If neither a format nor an `Accept` header is present, it defaults to AVIF. [↩](#user-content-fnref-format-selection-974927f853a57441f5211783d29ca9ae) [↩2](#user-content-fnref-format-selection-2-974927f853a57441f5211783d29ca9ae)
2. **Focal-point crops.** For `fit` or `markfit`, pass `null` as the crop position: `'fit' => ['crop', null, 50, 50]` or `'fit' => ['crop', null, 50, 50, 2]`. [↩](#user-content-fnref-focal-point-crops-974927f853a57441f5211783d29ca9ae) [↩2](#user-content-fnref-focal-point-crops-2-974927f853a57441f5211783d29ca9ae)
3. **Relative values.** These let you define width or height values as a percentage of the base image. Use a percentage number (from 0 to 100) followed by `w` for width or `h` for height. For example, `5w` means 5% of the base image's width, and `35h` is 35% of the image's height. [↩](#user-content-fnref-relative-values-974927f853a57441f5211783d29ca9ae) [↩2](#user-content-fnref-relative-values-2-974927f853a57441f5211783d29ca9ae) [↩3](#user-content-fnref-relative-values-3-974927f853a57441f5211783d29ca9ae) [↩4](#user-content-fnref-relative-values-4-974927f853a57441f5211783d29ca9ae) [↩5](#user-content-fnref-relative-values-5-974927f853a57441f5211783d29ca9ae)

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance97

Actively maintained with recent releases

Popularity17

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~9 days

Total

4

Last Release

16d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/c8b86130e9f7274fdc9b091bc20252a767b39ba6a25476d51ac0c2ae389b5ca9?d=identicon)[smallpicsio](/maintainers/smallpicsio)

---

Top Contributors

[![johnnynotsolucky](https://avatars.githubusercontent.com/u/4161106?v=4)](https://github.com/johnnynotsolucky "johnnynotsolucky (16 commits)")

---

Tags

craftcmsimagesprocessingsmallpicstransformerprocessingimagestransformercraftcmssmallpics

###  Code Quality

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/smallpics-craft-smallpics/health.svg)

```
[![Health](https://phpackages.com/badges/smallpics-craft-smallpics/health.svg)](https://phpackages.com/packages/smallpics-craft-smallpics)
```

###  Alternatives

[spicyweb/craft-neo

A Matrix-like field type with block hierarchy

393822.0k12](/packages/spicyweb-craft-neo)[craftcms/feed-me

Import content from XML, RSS, CSV or JSON feeds into entries, categories, Craft Commerce products, and more.

293967.9k41](/packages/craftcms-feed-me)[verbb/formie

The most user-friendly forms plugin for Craft.

102406.3k79](/packages/verbb-formie)[craftcms/commerce

Craft Commerce

240429.5k228](/packages/craftcms-commerce)[verbb/vizy

A flexible visual editor field for Craft.

4252.4k1](/packages/verbb-vizy)[verbb/hyper

A user-friendly links field for Craft.

24158.0k15](/packages/verbb-hyper)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
