GD
| Language | PHP (bundled extension ext/gd) |
|---|---|
| License | PHP License (bundled libgd: BSD-style GD license) |
| Repository | github.com/php/php-src (ext/gd) |
| Documentation | imagecreatefromgif, imagegif |
| Depends on | nothing (GIF support is built into libgd) |
| Read / write | yes / yes; first frame only, transparency, interlacing; no animation |
GD reads GIF with imagecreatefromgif into a palette image and writes with imagegif. GIF support is always compiled in, since it doesn’t need an external library. Transparency (one transparent palette index) is kept on load and save.
GD reads only the first frame of an animated GIF and can’t write animations. If your app accepts uploaded GIFs and resizes them with GD, animations become still images; use Imagick or Intervention Image instead.
Installation#
GD is compiled into most PHP packages; on Debian/Ubuntu: sudo apt install php-gd. Check with php -r 'var_dump(gd_info()["GIF Read Support"]);'.
Basic usage: load, resize and save a GIF with transparency#
Palette images must be converted to truecolor for good resampling, then back to a palette for GIF:
<?php
$src = imagecreatefromgif('logo.gif');
if ($src === false) {
exit("not a valid GIF\n");
}
$w = imagesx($src);
$h = imagesy($src);
$nw = intdiv($w, 2);
$nh = intdiv($h, 2);
$dst = imagecreatetruecolor($nw, $nh);
$transparent = imagecolorallocatealpha($dst, 0, 0, 0, 127);
imagefill($dst, 0, 0, $transparent);
imagecopyresampled($dst, $src, 0, 0, 0, 0, $nw, $nh, $w, $h);
imagetruecolortopalette($dst, false, 255); // 255 colors, no dithering
imagecolortransparent($dst, imagecolorclosestalpha($dst, 0, 0, 0, 127));
imagegif($dst, 'logo-small.gif');
How to check if a GIF is animated#
GD can’t tell you. Count image descriptors that follow a graphic control extension in the raw bytes:
function is_animated_gif(string $path): bool
{
$data = file_get_contents($path);
// graphic control extension followed by an image descriptor, more than once
return preg_match_all('/\x00\x21\xF9\x04.{4}\x00[\x2C\x21]/s', $data) > 1;
}
How to convert PNG to GIF#
$png = imagecreatefrompng('icon.png');
imagesavealpha($png, true);
imagetruecolortopalette($png, true, 256); // dithered palette
imagegif($png, 'icon.gif');
Partial transparency is lost: GIF has only fully transparent or opaque pixels.
How to read GIF dimensions without decoding#
[$w, $h, $type] = getimagesize('anim.gif');
if ($type === IMAGETYPE_GIF) {
echo "$w x $h\n"; // logical screen size
}
Tips#
imageinterlace($img, true)beforeimagegifwrites an interlaced GIF.imagegif($img)without a file name writes to the output; sendheader('Content-Type: image/gif')first.