学完这篇,你能判断自己的项目该用 GD、Imagick 还是第三方封装库,并且知道怎么一键检查环境、怎么安装、怎么避开最常见的几个坑。
第一步:先把三者的关系理清楚
它们不是并列的三选一,而是两层:
- GD 是 PHP 官方扩展,随 PHP 一起发布,函数式调用(
imagecreatefromjpeg、imagecopyresampled),只能处理基础格式:JPEG、PNG、GIF、WebP(较新版本)、AVIF(8.1+ 视编译而定)。
- Imagick 是 PECL 扩展,封装 ImageMagick,面向对象调用(
new Imagick()),支持上百种格式,包括 PDF、HEIC、TIFF、SVG,可做色彩空间转换、锐化、EXIF 处理。
- 第三方库(Intervention/Image、Gregwar/Image、Glide)是纯 PHP 封装,底层仍要用 GD 或 Imagick。它们不提供新的图像能力,只提供更好用的 API 和链式调用。
所以真正要决定的是「GD 还是 Imagick」,第三方库是上层选择。
第二步:检查当前服务器有什么
在动手之前先看环境,不要装完了才发现扩展早就存在:
php -m | grep -iE 'gd|imagick|exif'
# 看 GD 支持哪些格式
php -r "print_r(gd_info());"
# 看 Imagick 版本与支持的格式数量
php -r "var_dump(class_exists('Imagick'));"
php -r "echo count((new Imagick())->queryFormats()), PHP_EOL;"
注意:命令行(CLI)能看到扩展,不代表 PHP-FPM 加载了。生产环境务必在网页里跑一次 phpinfo() 或者用 extension_loaded('gd') 在业务代码里输出,两者版本/配置可能不是同一份。
第三步:安装,用面板或包管理器
宝塔等面板:软件商店 → 对应的 PHP 版本 → 设置 → 安装扩展 → 勾选 gd、imagick、exif。
命令行(Debian/Ubuntu):
sudo apt install php8.2-gd php8.2-imagick
sudo systemctl restart php8.2-fpm
CentOS/RHEL 用 yum install php-gd php-pecl-imagick,装完同样要重启 PHP-FPM。
第四步:GD 的最小可用示例
GD 的典型场景是上传头像、帖子配图缩略图这类「缩放 + 裁剪 + 压缩」,代码量不大:
$src = imagecreatefromjpeg($file);
[$w, $h] = getimagesize($file);
$dst = imagecreatetruecolor(300, 300);
imagecopyresampled($dst, $src, 0, 0, 0, 0, 300, 300, $w, $h);
imagejpeg($dst, $out, 82);
imagedestroy($src);
imagedestroy($dst);
要点就三个:用 imagecopyresampled 而不是 imagecopyresized(前者是平滑插值,后者是暴力采样,缩完锯齿明显);压缩质量别给 100,80–85 是体积和画质的平衡点;结束记得 imagedestroy 释放内存。
注意:手机拍的照片常带 EXIF 方向标记,GD 不认这个标记,直接缩放会「躺倒」。解法是先读 exif_read_data($file)['Orientation'],再按值调 imagerotate() / imageflip(),这一步很容易漏。
第五步:Imagick 用在哪
当你需要 GD 做不到的事,再上 Imagick:
$img = new Imagick($file);
$img->autoOrient(); // 自动处理 EXIF 方向,省掉上一步的手工判断
$img->setImageFormat('webp');
$img->setImageCompressionQuality(82);
$img->thumbnailImage(800, 0); // 等比缩放
$img->writeImage($out);
$img->clear();
autoOrient() 和格式转换(JPEG → WebP/AVIF)是它的核心价值。
注意:Imagick 有两个高频坑。一是共享主机/虚拟主机经常直接禁用这个扩展,本地跑得好,上线报 Class "Imagick" not found。二是 ImageMagick 有 policy.xml 安全策略,默认可能禁掉 PDF、MVG 等格式,报「not authorized」,要去 /etc/ImageMagick-6/policy.xml 调整。另外 Imagick 单进程内存占用明显高于 GD,处理大图前把 memory_limit 和 setResourceLimit 都设好。
第六步:要不要上第三方库
项目里图片处理只有两三处,直接用 GD 写十几行更省事,别为了一张缩略图引入依赖。如果图片逻辑分散在十几处、需要链式调用和统一水印/滤镜/响应式输出,那 Intervention/Image 值得装:
composer require intervention/image
use Intervention\Image\ImageManager;
$manager = new ImageManager(['driver' => 'gd']); // 或 'imagick'
$manager->make($file)->resize(800, null, fn($c) => $c->aspectRatio())->save($out, 82);
它的好处是驱动可切换:先按 GD 写,将来服务器装了 Imagick,改一个 driver 参数就换底层,业务代码不用动。
第七步:怎么选,看三条
- 只有缩略图、水印、验证码 → GD。零额外依赖,几乎不会被空间商禁掉。
- 要处理 HEIC、PDF、SVG,或要转 WebP/AVIF → Imagick。GD 在这些格式上要么不支持,要么依赖编译选项。
- 图片逻辑多、想统一 API → Intervention/Image,底层按服务器实际情况选驱动。
还有一条工程上的建议:代码里永远做运行时探测,别假设扩展一定在。比如图形验证码,可以用 extension_loaded('gd') 判断,没有 GD 就降级成纯文字算术题——Clara BBS 这类系统就是这么处理的,保证在残缺环境下功能不整个挂掉,而不是抛一个致命错误给用户看。
注意:无论选哪个,都要做上传校验。getimagesize() 返回 false 就不是真图片;再配合文件头白名单和二次校验,避免有人把 PHP 代码伪装成 jpg 传上来。扩展能处理图片,不负责替你挡攻击。
小结
- GD 是官方扩展、免安装、开销小,够用于缩放裁剪压缩;Imagick 是 PECL 扩展,强在格式覆盖和
autoOrient;第三方库只是 API 封装,底层仍靠这两者。
- 装完一定在 PHP-FPM 环境里验证,CLI 通过不等于网页可用。
- GD 记得用
imagecopyresampled、处理 EXIF 方向、及时 imagedestroy。
- Imagick 注意主机是否禁用、
policy.xml 是否拦格式、内存是否够。
- 图片逻辑少就手写 GD,多就上 Intervention/Image 并保留驱动可切换。
- 任何方案都要配上传校验和运行时扩展探测,做降级而不是崩溃。