Intervention/image · error · EncoderException

Failed to encode jp2 format

Error message

Failed to encode jp2 format

What it means

The Imagick driver's Jpeg2000Encoder flattens transparency onto a white background, sets format 'JP2' with JPEG compression and quality (src/Drivers/Imagick/Encoders/Jpeg2000Encoder.php:39-47), then serializes with getImagesBlob(). Any ImagickException is rethrown as EncoderException ('Failed to encode jp2 format') with the original as previous. JPEG 2000 output needs ImageMagick built with the OpenJPEG delegate, which many default builds exclude - the previous exception then says 'no encode delegate for this image format'.

Source

Thrown at src/Drivers/Imagick/Encoders/Jpeg2000Encoder.php:54

        }

        try {
            $imagick = clone $image->core()->native();
            $imagick->setImageBackgroundColor('white');
            $imagick->setBackgroundColor('white');
            $imagick->setFormat($format);
            $imagick->setImageFormat($format);
            $imagick->setCompression($compression);
            $imagick->setImageCompression($compression);
            $imagick->setCompressionQuality($this->quality);
            $imagick->setImageCompressionQuality($this->quality);

            $result = new EncodedImage($imagick->getImagesBlob(), 'image/jp2');
            $imagick->clear();

            return $result;
        } catch (ImagickException $e) {
            throw new EncoderException('Failed to encode jp2 format', previous: $e);
        }
    }
}

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Read $e->getPrevious()->getMessage() to confirm the delegate error.
  2. Check Imagick::queryFormats('JP2') on the failing host.
  3. Install the OpenJPEG delegate (apt-get install libopenjp2-7-dev / dnf install openjpeg2-devel) and an ImageMagick build linked to it, then rebuild the imagick extension.
  4. If JPEG 2000 is not a hard requirement, encode with toJpeg() or toWebp(), which are supported everywhere.

Example fix

// before
$encoded = $image->toJpeg2000(quality: 80);

// after
$jp2Supported = in_array('JP2', Imagick::queryFormats('JP2'), true);
$encoded = $jp2Supported ? $image->toJpeg2000(quality: 80) : $image->toJpeg(quality: 80);
Defensive patterns

Strategy: validation

Validate before calling

$jp2Supported = in_array('JP2', Imagick::queryFormats('JP2'), true);
if (!$jp2Supported) {
    throw new RuntimeException('JPEG 2000 encoding unavailable: ImageMagick lacks the OpenJPEG delegate');
}
$encoded = $image->toJpeg2000();

Try / catch

try {
    $encoded = $image->toJpeg2000(quality: 80);
} catch (EncoderException $e) {
    $reason = $e->getPrevious()?->getMessage() ?? $e->getMessage();
    $encoded = $image->toJpeg(quality: 80); // degrade, then log $reason
}

Prevention

When it happens

Trigger: Calling toJpeg2000() or encoding to a *.jp2 target on the Imagick driver when setFormat('JP2')/setImageFormat('JP2') throws because the OpenJPEG coder is missing: php -r "var_dump((new Imagick())->queryFormats('JP2'));" returns an empty array. Also when quality-setting or blob serialization fails in partially capable builds.

Common situations: RHEL/CentOS and Alpine default ImageMagick packages without openjpeg; archival/scanning workflows migrating to JPEG 2000; environments where jp2 decode works but encode does not (asymmetric delegate sets).

Related errors


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