PHP RFC: Update ext/gd to latest features
- Version: 0.1
- Date: 2026-07-06
- Author: pajoye@php.net
- Status: Draft (Later in the RFC process “Under Discussion”, “Voting”, and finally “Accepted”, “Declined” or “Implemented”)
- Implementation: https://github.com/...
- Discussion thread: https://news-web.php.net/php.internals/… (The email should appear on https://news-web.php.net/php.internals/ a few minutes after sending it)
- Voting thread: tbd
Introduction
Add and expose libgd's 2.4 features:
* New codecs and codecs completeness
- QOI (builtin)
- JXL, full support, including animations (uses libjxl)
- UHDR (uses libultrahdr)
- GIF, added full support, animations, read and write (builtin)
- BMP, added full support but OS/2 bmp (builtin)
- webp, full support for all formats and animations (use libwebp)
- TIFF. full support, single or multiple pages, read and write
- PNG, full support for all formats, add with options (extending the imagepng($im, $basefilter) exposing all options
- for formats supporting, ability to read/write metadata as raw data, which can be then processed (libexif, pure php, etc) and used back to write the image)
* New 2D vector APIs * Perceptual Diff (can finally be used for more arch resilient tests in php)
Proposal
Expose new libgd features and enhancement to ext/gd
- new codecs
- new 2D vector drawing APIs (canvas-like)
- Ability to do more resilient testing from php
Examples
2D Vector APIs
Gradient modes and compositions
Some drawings
Backward Incompatible Changes
Color match fix breaks BC as the correct behavior is implemented now
Correct FT rendering and BBox on angle, baseline etc. affects slightly bounding box on axis aligned texts, and significantly more on rotated texts. The bug in the FT2 implementations actually prevented accurate rendering.
Codecs
PNG
<?php /** * @generate-class-entries * @generate-c-enums */ namespace Gd\Codec { /** @strict-properties */ class CodecException extends \RuntimeException { } } namespace Gd\Png { #ifdef HAVE_GD_PNG_WRITE_OPTIONS enum Filter { case None; case Sub; case Up; case Average; case Paeth; } enum CompressionStrategy { case Default; case Filtered; case HuffmanOnly; case Rle; case Fixed; } /** @strict-properties */ final readonly class WriteOptions { public int $compressionLevel; public array $filters; public CompressionStrategy $compressionStrategy; /** @param list<Filter> $filters */ public function __construct( int $compressionLevel = -1, array $filters = [], CompressionStrategy $compressionStrategy = CompressionStrategy::Default, ) {} } final class Codec { private function __construct() {} public static function toFile( \GdImage $image, string $path, WriteOptions $options = new WriteOptions(), ): void {} /** @param resource $stream */ public static function toStream( \GdImage $image, $stream, WriteOptions $options = new WriteOptions(), ): void {} public static function toString( \GdImage $image, WriteOptions $options = new WriteOptions(), ): string {} } #endif }
<?php /** * @generate-class-entries * @generate-c-enums */ namespace Gd\Codec { /** @strict-properties */ class CodecException extends \RuntimeException { } } namespace Gd\Qoi { #ifdef HAVE_GD_QOI enum Colorspace { case SRGB; case Linear; } final class Codec { private function __construct() {} public static function fromFile(string $path): \GdImage {} /** @param resource $stream */ public static function fromStream($stream): \GdImage {} public static function fromString(string $bytes): \GdImage {} public static function toFile( \GdImage $image, string $path, Colorspace $colorspace = Colorspace::SRGB, ): void {} /** @param resource $stream */ public static function toStream( \GdImage $image, $stream, Colorspace $colorspace = Colorspace::SRGB, ): void {} public static function toString( \GdImage $image, Colorspace $colorspace = Colorspace::SRGB, ): string {} } #endif }
Proposed PHP Version(s)
PHP 8.6.0
RFC Impact
To the Ecosystem
New APIs exposed, no new syntax.
To Existing Extensions
ext/gd
Open Issues
Make sure there are no open issues when the vote starts!
Future Scope
latest libgd prepares the road to libgd 3.0 which adds more internal buffer formats and ability to handle HDR natively. Fromats like actual 32bits ARGB, floating points buffers, etc.
Voting Choices
Pick a title that reflects the concrete choice people will vote on.
Please consult the php/policies repository for the current voting guidelines.
Primary Vote requiring a 2/3 majority to accept the RFC:
Patches and Tests
Implementation
There are two separate PRs:
-
- The winbuilds already include the new dependencyes
- The additions and changes to ext/gd once the sync is merged is not yet pushed
References
Rejected Features
Keep this updated with features that were discussed on the mail lists.
Changelog
If there are major changes to the initial proposal, please include a short summary with a date or a link to the mailing list announcement here, as not everyone has access to the wikis' version history.