Intervention/image · error · ModifierException

Failed to apply Intervention\Image\Drivers\Gd\Modifiers\Shar

Error message

Failed to apply Intervention\Image\Drivers\Gd\Modifiers\SharpenModifier, unable to set convolution matrix

What it means

sharpen() builds a 3x3 convolution matrix from the level and applies imageconvolution($gd, $matrix, 1, 0) to every frame, throwing ModifierException on a false return. GD returns false when it cannot convolve the given image - most notably for palette (indexed) images - or when the native GdImage is invalid. The concrete in-library chain: reduceColors() converts frames to palette images via imagetruecolortopalette(), so sharpening right after a color reduction is the standard way to hit this.

Source

Thrown at src/Drivers/Gd/Modifiers/SharpenModifier.php:27

use Intervention\Image\Interfaces\SpecializedInterface;
use Intervention\Image\Modifiers\SharpenModifier as GenericSharpenModifier;

class SharpenModifier extends GenericSharpenModifier implements SpecializedInterface
{
    /**
     * {@inheritdoc}
     *
     * @see ModifierInterface::apply()
     *
     * @throws ModifierException
     */
    public function apply(ImageInterface $image): ImageInterface
    {
        $matrix = $this->matrix();
        foreach ($image as $frame) {
            $result = imageconvolution($frame->native(), $matrix, 1, 0);
            if ($result === false) {
                throw new ModifierException(
                    'Failed to apply ' . self::class . ', unable to set convolution matrix',
                );
            }
        }

        return $image;
    }

    /**
     * Create matrix to be used by imageconvolution()
     *
     * @return array<array<float>>
     */
    private function matrix(): array
    {
        $min = $this->level >= 10 ? $this->level * -0.01 : 0;
        $max = $this->level * -0.025;
        $abs = ((4 * $min + 4 * $max) * -1) + 1;

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Reorder the pipeline: sharpen first, reduceColors() last
  2. Convert frames back to truecolor before sharpening: foreach ($image as $frame) { imagepalettetotruecolor($frame->native()); }
  3. Re-decode the image from source if the native state is suspect
  4. Catch ModifierException and skip sharpening

Example fix

// before: sharpen after quantization (palette frames)
$image->reduceColors(64)->sharpen(10);

// after: sharpen before quantization
$image->sharpen(10)->reduceColors(64);
Defensive patterns

Strategy: try-catch

Validate before calling

foreach ($image as $frame) {
    $native = $frame->native();
    if (!imageistruecolor($native)) {
        imagepalettetotruecolor($native); // imageconvolution needs truecolor frames
    }
}

$image->sharpen(10);

Try / catch

use Intervention\Image\Exceptions\ModifierException;

try {
    $image->sharpen(10);
} catch (ModifierException $e) {
    $logger?->warning('Sharpen failed (palette frame?): ' . $e->getMessage());
}

Prevention

When it happens

Trigger: $image->reduceColors(64)->sharpen(10); custom code that replaced frame natives with broken GdImage resources; applying sharpen() to a hand-built palette core; the library's test suite forcing imageconvolution() to fail (testApplyThrowsWhenSpecializedWithoutOverride).

Common situations: GIF-oriented pipelines that quantize colors early then sharpen; memory-conscious flows that reduce colors before detail work; test harnesses for the failure branch.

Related errors


AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23). Data as JSON: /api/errors/8a326bba43a5c6a6. Report an issue: GitHub.