Encoders & optimizers

Last updated: August 21st 2026

Rule of thumb: use the native encoder plus optimizer binaries in config. Write a custom encoder only when you must replace the encode step — see examples/.

Mental model

Driver processes pixels
        ↓
Encoder writes format bytes (GD / Imagick / Libvips)
        ↓
Optimizer optionally post-processes those bytes (jpegoptim, cwebp, …)
        ↓
Storage writes the final object
optimizeType
'optimizers' => [
    'enabled' => true,
    // job     = serve the file first; jpegoptim/optipng/etc. overwrite later via BoldMinded Queue
    // runtime = block until post-optimize finishes (useful for debugging / no queue)
    'optimizeType' => 'job',
    'jpeg' => 'jpegoptim',
    'png' => 'oxipng',z    'webp' => null,
    'avif' => null,
],

Same-format post-optimizers (jpegoptim, optipng, oxipng, pngquant) can be deferred with job when the BoldMinded Queue add-on is installed. Without the queue bridge, Super Images falls back to inline (runtime) so derivatives are still optimized.

Format converters (cwebp, avifenc) always run during generation so the stored object is already the correct type.

With job, the page can return storage URLs as soon as resize/encode finishes. The queue then reads the stored object (local disk or S3 download), optimizes, and overwrites the same path/URL.

Encoder options

'encoders' => [
    'jpeg' => ['quality' => 82],
    'jpg' => ['quality' => 82],
    'png' => [],
    'webp' => [
        'quality' => 80,
        'method' => 4, // passed to cwebp as -m when using PNG→cwebp
    ],
    'avif' => ['quality' => 65],
],

Custom CLI arguments on encoders / optimizers

When a format uses an external tool (for example optimizers.webp = 'cwebp'), you can override the full argument list after the binary. Prefer a key/value map:
'encoders' => [
    'webp' => [
        'quality' => 80,
        'arguments' => [
            '-q' => '{quality}',
            '-m' => 6,
            '-sharp_yuv' => true,
            '-o' => '{output}',
            '_' => ['{input}'], // trailing positionals
        ],
    ],
],

A flat token list still works: ['-q', '{quality}', '{input}', '-o', '{output}'].

Per-format optimizer override with binary + arguments:

'jpeg' => [
    'tool' => 'jpegoptim',
    'binary' => $_ENV['SUPER_IMAGES_JPEGOPTIM'] ?? '/usr/bin/jpegoptim',
    // Replaces the built-in recipe. Tokens: {input} {output} {quality} {effort} {method}
    'arguments' => [
        '--stdout' => true,
        '--strip-all' => true,
        '--max' => 85,
        '_' => ['{input}'],
    ],
],
Rules for key/value maps:
ValueResult
true or ''Flag only (--strip-all)
false or nullSkipped
scalarFlag + value as two argv tokens (--max, 85)
key ending in =Single token (--max=85)
'_' / 'positional(s)'Trailing positionals list
integer keysPositional token (value only)

arguments may also be a flat list or a whitespace-separated string. Alias key: args.

Optimizer-level arguments win over encoder-level arguments when both are set. When arguments is omitted, Super Images uses built-in recipes (jpegoptim stdout strip, cwebp with -q / -m / -sharp_yuv, etc.).

All execution goes through ProcessRunner (argument arrays only).

Optimizer binaries

'optimizers' => [
    'enabled' => true,
    'optimizeType' => 'runtime',
    'binaries' => [
        'jpegoptim' => $_ENV['SUPER_IMAGES_JPEGOPTIM'] ?? 'jpegoptim',
        'oxipng' => $_ENV['SUPER_IMAGES_OXIPNG'] ?? 'oxipng',
        'optipng' => $_ENV['SUPER_IMAGES_OPTIPNG'] ?? 'optipng',
        'pngquant' => $_ENV['SUPER_IMAGES_PNGQUANT'] ?? 'pngquant',
        'cwebp' => $_ENV['SUPER_IMAGES_CWEBP'] ?? 'cwebp',
        'avifenc' => $_ENV['SUPER_IMAGES_AVIFENC'] ?? 'avifenc',
    ],
    'jpeg' => 'jpegoptim',
    'png' => 'oxipng',
    'webp' => null,
    'avif' => null,
],

Resolution order: per-format binary override → optimizers.binaries[tool] → tool name on PATH.

CP → Encoders & Optimizers shows resolved paths and an i tooltip with the apt command when something is missing.

Install missing tools (Ubuntu)

Live servers are assumed to be Ubuntu. CP install hints and doctor suggestions use apt-get only.
Toolapt
jpegoptimsudo apt-get install -y jpegoptim
optipngsudo apt-get install -y optipng
pngquantsudo apt-get install -y pngquant
cwebpsudo apt-get install -y webp
avifencsudo apt-get install -y libavif-bin
oxipngoften via cargo; or use optipng instead
php-gdsudo apt-get install -y php-gd (use php8.x-gd for your PHP version)
php-imagicksudo apt-get install -y php-imagick
libvipssudo apt-get install -y libvips42 libvips-dev then composer require jcupitt/vips
Recommended .env paths
SUPER_IMAGES_JPEGOPTIM=/usr/bin/jpegoptim
SUPER_IMAGES_CWEBP=/usr/bin/cwebp
SUPER_IMAGES_OXIPNG=/usr/bin/oxipng

If an env var is empty, Super Images falls back to the tool name and searches PATH. Use $_ENV['…'] in config (ExpressionEngine loads .env into $_ENV).

JPEG and alpha

JPEG does not support transparency. When the source has an alpha channel, all drivers flatten onto a white background (#ffffff) before JPEG encode so output matches WebP/AVIF visually (no “ghost” overlay).

Override the flatten colour via encoder extra.background if needed.


Verify

php eecli.php super_images:doctor