Intervention/image · error · ModifierException

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

Error message

Failed to apply Intervention\Image\Drivers\Imagick\Modifiers\DrawPolygonModifier, unable to build ImagickDraw object

What it means

This ModifierException is thrown by the Imagick driver when drawing a polygon with $image->drawPolygon() and the native ImagickDraw object cannot be built. The private polygon() method in src/Drivers/Imagick/Modifiers/DrawPolygonModifier.php:47 wraps ImagickException and ImagickDrawException raised by setFillColor(), setStrokeColor(), setStrokeWidth() or ImagickDraw::polygon() while converting your drawable into an ImagickDraw. The original native failure is chained as the previous exception, so inspect getPrevious() for the real cause.

Source

Thrown at src/Drivers/Imagick/Modifiers/DrawPolygonModifier.php:62

     *
     * @throws ModifierException
     */
    private function polygon(ImagickPixel $backgroundColor, ImagickPixel $borderColor): ImagickDraw
    {
        try {
            $polygon = new ImagickDraw();
            $polygon->setFillColor($backgroundColor);

            if ($this->drawable->hasBorder()) {
                $polygon->setStrokeColor($borderColor);
                $polygon->setStrokeWidth($this->drawable->borderSize());
            }

            $polygon->polygon($this->points());

            return $polygon;
        } catch (ImagickException | ImagickDrawException $e) {
            throw new ModifierException(
                'Failed to apply ' . self::class . ', unable to build ImagickDraw object',
                previous: $e,
            );
        }
    }

    /**
     * Return points of drawable in processable form for ImagickDraw.
     *
     * @return array<array<string, int>>
     */
    private function points(): array
    {
        $points = [];
        foreach ($this->drawable as $point) {
            $points[] = ['x' => $point->x(), 'y' => $point->y()];
        }

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Inspect the chained previous exception (catch ModifierException, log $e->getPrevious()) to see the exact native Imagick error
  2. Sanitize all polygon points: cast coordinates to int, reject NAN/INF, and keep values within the image dimensions
  3. Ensure any border width set in the draw callback is a non-negative number
  4. Increase PHP memory_limit and check ImageMagick resource limits if drawing on large images
  5. Review /etc/ImageMagick-*/policy.xml for memory and width/height caps if the previous exception mentions policy or resources
  6. Try the GD driver (ImageManager::withDriver(Driver::class)) to isolate an ImageMagick-specific problem

Example fix

// before
$points = [[acos(2) * 100, $y], [$x2, $y2], [$x3, $y3]]; // acos(2) = NAN leaks in
$image->drawPolygon($points, fn($draw) => $draw->background('ff0'));

// after
$safe = array_map(
    fn(array $p): array => [
        'x' => (int) max(0, min($image->width() - 1, (int) $p['x'])),
        'y' => (int) max(0, min($image->height() - 1, (int) $p['y'])),
    ],
    $points,
);
$image->drawPolygon($safe, fn($draw) => $draw->background('ff0'));
Defensive patterns

Strategy: try-catch

Validate before calling

$points = array_map(
    fn(array $p): array => [
        'x' => (int) $p['x'],
        'y' => (int) $p['y'],
    ],
    $points,
);
$invalid = array_filter($points, fn($p) =>
    !is_finite($p['x']) || !is_finite($p['y'])
);
if (count($invalid) > 0 || count($points) < 3) {
    throw new \InvalidArgumentException('Polygon needs >= 3 finite integer points');
}

Type guard

/** @param array<int,array{x:int,y:int}> $points */
function isValidPolygonPoints(array $points, int $width, int $height): bool
{
    if (count($points) < 3) {
        return false;
    }
    foreach ($points as $p) {
        if (!isset($p['x'], $p['y']) || !is_int($p['x']) || !is_int($p['y'])) {
            return false;
        }
        if ($p['x'] < -$width || $p['x'] > 2 * $width || $p['y'] < -$height || $p['y'] > 2 * $height) {
            return false;
        }
    }
    return true;
}

Try / catch

use Intervention\Image\Exceptions\ModifierException;

try {
    $image->drawPolygon($points, $callback);
} catch (ModifierException $e) {
    $native = $e->getPrevious();
    Log::warning('Polygon draw failed: ' . ($native?->getMessage() ?? $e->getMessage()));
    throw $e;
}

Prevention

When it happens

Trigger: Calling $image->drawPolygon($points, $callback) where a point coordinate is NAN, INF, a non-numeric value, or an integer that overflows ImageMagick's internal limits; setting a border_size that is negative or non-finite via the draw callback; passing a background/border color string that decodes to an invalid ImagickPixel; memory exhaustion while instantiating ImagickDraw.

Common situations: Polygon vertices computed from unvalidated user input or floating-point math (NaN from 0/0 divisions); drawing polygons on very large canvases under a low PHP memory_limit; shared-hosting ImageMagick installations with restrictive policy.xml settings; ImageMagick/imagick extension version mismatches after a server upgrade.

Related errors


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