{"record":{"id":"8a326bba43a5c6a6","repo":"Intervention/image","slug":"failed-to-apply-intervention-image-drivers-gd-modi-8a326b","errorCode":null,"errorMessage":"Failed to apply Intervention\\Image\\Drivers\\Gd\\Modifiers\\SharpenModifier, unable to set convolution matrix","messagePattern":"Failed to apply Intervention\\\\Image\\\\Drivers\\\\Gd\\\\Modifiers\\\\SharpenModifier, unable to set convolution matrix","errorType":"exception","errorClass":"ModifierException","httpStatus":null,"severity":"error","filePath":"src/Drivers/Gd/Modifiers/SharpenModifier.php","lineNumber":27,"sourceCode":"use Intervention\\Image\\Interfaces\\SpecializedInterface;\nuse Intervention\\Image\\Modifiers\\SharpenModifier as GenericSharpenModifier;\n\nclass SharpenModifier extends GenericSharpenModifier implements SpecializedInterface\n{\n    /**\n     * {@inheritdoc}\n     *\n     * @see ModifierInterface::apply()\n     *\n     * @throws ModifierException\n     */\n    public function apply(ImageInterface $image): ImageInterface\n    {\n        $matrix = $this->matrix();\n        foreach ($image as $frame) {\n            $result = imageconvolution($frame->native(), $matrix, 1, 0);\n            if ($result === false) {\n                throw new ModifierException(\n                    'Failed to apply ' . self::class . ', unable to set convolution matrix',\n                );\n            }\n        }\n\n        return $image;\n    }\n\n    /**\n     * Create matrix to be used by imageconvolution()\n     *\n     * @return array<array<float>>\n     */\n    private function matrix(): array\n    {\n        $min = $this->level >= 10 ? $this->level * -0.01 : 0;\n        $max = $this->level * -0.025;\n        $abs = ((4 * $min + 4 * $max) * -1) + 1;","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/Intervention/image/blob/5598b9e39751c34afc5cdee84abef77f92c26f68/src/Drivers/Gd/Modifiers/SharpenModifier.php#L9-L45","documentation":"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.","triggerScenarios":"$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).","commonSituations":"GIF-oriented pipelines that quantize colors early then sharpen; memory-conscious flows that reduce colors before detail work; test harnesses for the failure branch.","solutions":["Reorder the pipeline: sharpen first, reduceColors() last","Convert frames back to truecolor before sharpening: foreach ($image as $frame) { imagepalettetotruecolor($frame->native()); }","Re-decode the image from source if the native state is suspect","Catch ModifierException and skip sharpening"],"exampleFix":"// before: sharpen after quantization (palette frames)\n$image->reduceColors(64)->sharpen(10);\n\n// after: sharpen before quantization\n$image->sharpen(10)->reduceColors(64);","handlingStrategy":"try-catch","validationCode":"foreach ($image as $frame) {\n    $native = $frame->native();\n    if (!imageistruecolor($native)) {\n        imagepalettetotruecolor($native); // imageconvolution needs truecolor frames\n    }\n}\n\n$image->sharpen(10);","typeGuard":null,"tryCatchPattern":"use Intervention\\Image\\Exceptions\\ModifierException;\n\ntry {\n    $image->sharpen(10);\n} catch (ModifierException $e) {\n    $logger?->warning('Sharpen failed (palette frame?): ' . $e->getMessage());\n}","preventionTips":["Order the pipeline: sharpen before reduceColors() - quantize last.","Convert frames back to truecolor after any palette conversion before convolving.","Avoid replacing frame natives with hand-made GD resources."],"tags":["gd","sharpen","imageconvolution","filter-failure","palette","truecolor"],"backgroundTag":"gd-imageconvolution-failed","analyzedSha":"5598b9e39751c34afc5cdee84abef77f92c26f68","analyzedAt":"2026-08-23T02:17:31.068Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}