GD
| Language | PHP (C extension, bundled with PHP) |
|---|---|
| License | PHP License (extension), libgd: BSD-style |
| Repository | php-src ext/gd |
| Documentation | imageavif, imagecreatefromavif |
| Depends on | libavif (with an AV1 decoder and encoder), enabled at build time with --with-avif |
| Read / write | yes / yes, 8-bit, alpha (PHP 8.1+) |
GD is PHP’s built-in image extension. Since PHP 8.1 it reads AVIF with imagecreatefromavif() and writes it with imageavif(), when PHP was built with --with-avif (libavif). Many distribution packages include it, but the official Docker images need it enabled explicitly and some hosts don’t have it: check before relying on it.
GD works with 8-bit truecolor images, so 10/12-bit AVIF is reduced to 8 bits, and it doesn’t read animated AVIF frames or keep Exif metadata. Resizing quality is basic. For more, use Imagick.
Installation#
# Debian / Ubuntu
sudo apt install php-gd
# Docker (official php image): build GD with AVIF
apt-get install -y libavif-dev
docker-php-ext-configure gd --with-avif --with-jpeg --with-webp
docker-php-ext-install gd
Check support:
<?php
var_dump(function_exists('imageavif')); // bool(true)
var_dump((imagetypes() & IMG_AVIF) !== 0); // bool(true)
Basic usage: convert JPEG to AVIF#
<?php
$image = imagecreatefromjpeg('photo.jpg');
if ($image === false) {
exit("cannot read photo.jpg\n");
}
printf("%d x %d\n", imagesx($image), imagesy($image));
imageavif($image, 'photo.avif', 60, 6); // quality 0..100, speed 0..10
$back = imagecreatefromavif('photo.avif');
imagepng($back, 'photo.png');
$quality -1 means the default (52); $speed -1 means the default (6). Lower speed gives smaller files and takes longer.
How to convert PNG to AVIF and keep transparency#
<?php
$image = imagecreatefrompng('logo.png');
imagealphablending($image, false);
imagesavealpha($image, true); // keep the alpha channel
imageavif($image, 'logo.avif', 70);
How to resize and save as AVIF#
<?php
$src = imagecreatefromjpeg('large.jpg');
$thumb = imagescale($src, 800); // 800 pixels wide, height keeps aspect ratio
imageavif($thumb, 'thumb.avif', 55, 8);
How to get AVIF width and height#
<?php
[$width, $height, $type] = getimagesize('photo.avif');
var_dump($type === IMAGETYPE_AVIF);
getimagesize() reads only the header. It returns real AVIF dimensions since PHP 8.2 (PHP 8.1 reports 0 x 0).
How to send AVIF to the browser#
<?php
header('Content-Type: image/avif');
imageavif($image); // no file: writes to output
Tips#
- Check the
Acceptrequest header forimage/avifbefore serving AVIF to old browsers, or use a<picture>element with a JPEG fallback. - AVIF encoding is CPU-heavy: generate files once and cache them instead of encoding on every request.
- As of PHP 8.4, invalid
$qualityor$speedvalues throw aValueError.