Intervention/image · error · ModifierException

Failed to apply Intervention\Image\Drivers\Imagick\Modifiers

Error message

Failed to apply Intervention\Image\Drivers\Imagick\Modifiers\ColorizeModifier, unable to adjust image colors

What it means

Thrown by the Imagick ColorizeModifier when the chained per-channel levelImage() calls (red && green && blue, bounded by the quantum range) return false during $image->colorize(). A false from any single channel triggers it, so one failing channel aborts the whole modifier. Levels are normalized from -100..100 to black/white points before the call.

Source

Thrown at src/Drivers/Imagick/Modifiers/ColorizeModifier.php:41

        $blue = $this->normalizeLevel($this->blue);

        foreach ($image as $frame) {
            try {
                $qrange = $frame->native()->getQuantumRange();
            } catch (ImageException $e) {
                throw new ModifierException(
                    'Failed to apply ' . self::class . ', unable to get quantum range',
                    previous: $e,
                );
            }

            try {
                $result = $frame->native()->levelImage(0, $red, $qrange['quantumRangeLong'], Imagick::CHANNEL_RED)
                    && $frame->native()->levelImage(0, $green, $qrange['quantumRangeLong'], Imagick::CHANNEL_GREEN)
                    && $frame->native()->levelImage(0, $blue, $qrange['quantumRangeLong'], Imagick::CHANNEL_BLUE);

                if ($result === false) {
                    throw new ModifierException(
                        'Failed to apply ' . self::class . ', unable to adjust image colors',
                    );
                }
            } catch (ImageException $e) {
                throw new ModifierException(
                    'Failed to apply ' . self::class . ', unable to adjust image colors',
                    previous: $e,
                );
            }
        }

        return $image;
    }

    private function normalizeLevel(int $level): int
    {
        return $level > 0 ? intval(round($level / 5)) : intval(round(($level + 100) / 100));
    }

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Convert to sRGB before colorizing: $image->colorspace(RgbColorspace) — per-channel RGB leveling is the tested path.
  2. If dimensions are extreme, raise ImageMagick resource limits or operate on a scaled copy.
  3. Confirm the source decodes fully; re-encode uploads once before filter chains.
  4. Update ImageMagick if ordinary RGB colorize fails reproducibly (CLI check: convert in.png -level 0,255,1 out.png).

Example fix

// before
$image->colorize(80, 0, 0); // channel leveling fails on CMYK source

// after
$image->colorspace(\Intervention\Image\Colors\Rgb\Colorspace::class)->colorize(80, 0, 0);
Defensive patterns

Strategy: fallback

Validate before calling

// avoid the common per-channel failure mode up front
if (!$image->colorspace() instanceof \Intervention\Image\Colors\Rgb\Colorspace) {
    $image = $image->colorspace(\Intervention\Image\Colors\Rgb\Colorspace::class);
}

Try / catch

use Intervention\Image\Exceptions\ModifierException;
try {
    $image->colorize(50, 25, 0);
} catch (ModifierException $e) {
    try {
        $image->colorspace(\Intervention\Image\Colors\Rgb\Colorspace::class)->colorize(50, 25, 0);
    } catch (ModifierException $e2) {
        throw $e2;
    }
}

Prevention

When it happens

Trigger: Calling $image->colorize() where ImageMagick's levelImage reports failure for a channel: degraded wand state, images in colorspaces where per-channel leveling is unsupported, or resource exhaustion mid-operation. The false-return path carries no previous exception.

Common situations: Colorizing CMYK or exotic-colorspace images; processing very large images under tight policy.xml limits; colorizing frames of partially corrupt animated files.

Related errors


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