Intervention/image · error · ModifierException

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

Error message

Failed to apply Intervention\Image\Drivers\Gd\Modifiers\TrimModifier, unable to create canvas

What it means

The GD trim() modifier first copies the source image onto a fresh truecolor canvas (transparencySafeVersion) so imagecropauto() cannot destroy alpha information. That copy is created with imagecreatetruecolor($width, $height), and it returned false, meaning GD could not allocate the canvas. In practice this is almost always PHP's memory_limit: a truecolor canvas costs roughly width x height x 5 bytes on top of the memory already held by the source image.

Source

Thrown at src/Drivers/Gd/Modifiers/TrimModifier.php:75

     * Copy the given GdImage to a fresh true color canvas that has no transparent color set.
     *
     * imagecropauto() internally drops every pixel that matches the image's "transparent
     * color". palette images that were converted to true color while decoding carry over
     * a bogus transparent color, which would turn all transparent areas opaque during the
     * crop. transfer the image to a fresh true color canvas without a transparent color
     * to preserve the alpha channel.
     *
     * @throws ModifierException
     */
    private function transparencySafeVersion(GdImage $gd): GdImage
    {
        $width = imagesx($gd);
        $height = imagesy($gd);

        $canvas = imagecreatetruecolor($width, $height);

        if ($canvas === false) {
            throw new ModifierException(
                'Failed to apply ' . self::class . ', unable to create canvas',
            );
        }

        imagealphablending($canvas, false);
        imagesavealpha($canvas, true);

        // pre-fill with the original transparent color (if any).
        $transparent = imagecolortransparent($gd);
        if ($transparent !== -1) {
            imagefill($canvas, 0, 0, $transparent);
        }

        // copy resolution to canvas
        $resolution = imageresolution($gd);
        if (is_array($resolution) && array_key_exists(0, $resolution) && array_key_exists(1, $resolution)) {
            imageresolution($canvas, $resolution[0], $resolution[1]);
        }

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Raise the memory budget for the image worker: ini_set('memory_limit', '512M'); or set memory_limit in php.ini / the PHP-FPM pool.
  2. Budget the GD cost up front (about width*height*5 bytes for the trim canvas on top of the source) and reject or downscale oversized inputs with scaleDown() before trim().
  3. Switch the ImageManager to the Imagick driver, which does not allocate a monolithic PHP-memory canvas for trimming.
  4. Move trimming into a dedicated queue job so the operation is not bound by the web request's memory_limit.

Example fix

// before
$image = ImageManager::gd()->read('poster.tif')->trim();

// after: GD trim() duplicates the image onto a new truecolor canvas (~5 bytes/pixel)
ini_set('memory_limit', '1G');
$image = ImageManager::gd()->read('poster.tif')->trim();
Defensive patterns

Strategy: validation

Validate before calling

// GD trim() duplicates the image onto a new truecolor canvas (~5 bytes/pixel)
$bytesNeeded = $image->width() * $image->height() * 5;
$bytesFree = return_bytes(ini_get('memory_limit')) - memory_get_usage();
if ($bytesNeeded > $bytesFree) {
    $image = $image->scaleDown(width: 4000); // or reject with a clear message
}
$image->trim();

Try / catch

try { $image->trim(); } catch (ModifierException $e) { error_log(...); $image = $image->scaleDown(width: 4000)->trim(); }

Prevention

When it happens

Trigger: Calling trim() on the GD driver for a large image (a 6000x4000 photo needs ~120 MB just for the duplicate canvas) while memory_limit is 128M/256M; pipelines that keep several GdImage buffers alive (resize + trim + watermark) so the extra canvas pushes the request over the limit.

Common situations: Phone or camera originals (12-50 MP) trimmed on shared hosting with default memory_limit; long-running queue workers whose memory accumulates over many images; high-DPI scans.

Related errors


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