本文目录导读:

- 方案一:使用 GD 库(PHP 内置,无需额外安装)
- 方案二:使用 Imagick 扩展(推荐,功能强大)
- 方案三:使用第三方库(如 Intervention Image)
- 方案四:调用外部 API / 云服务(大规模、高性能)
- 总结建议
在 PHP 项目中压缩图片资源,通常有几种主流的方案,从使用 PHP 扩展或库到集成外部服务。
以下是几种最常用、最有效的方法,按推荐程度排序:
使用 GD 库(PHP 内置,无需额外安装)
优点: PHP 标配,大多数环境都支持,简单快速。 缺点: 压缩率一般,不支持 WebP(旧版本),功能相对基础。
核心原理: 读取图片 -> 重新采样/调整尺寸 -> 设置输出质量 -> 保存。
<?php
function compressImageGD($sourcePath, $destinationPath, $quality = 75) {
// 1. 获取图片信息
$info = getimagesize($sourcePath);
$mime = $info['mime'];
// 2. 根据类型创建图像资源
switch ($mime) {
case 'image/jpeg':
$image = imagecreatefromjpeg($sourcePath);
break;
case 'image/png':
$image = imagecreatefrompng($sourcePath);
// PNG 的 quality 参数在 GD 中实际上是压缩级别 (0-9),需要转换
// quality 0 (无压缩) -> 9 (最大压缩);习惯上我们想用高quality保持画质,但这里相反
// 如果不改变尺寸,可以使用 imagepng, quality 参数 0-9
// 更推荐用 imagejpeg 转一遍(会损失透明度,但压缩率高)
imagepng($image, $destinationPath, 9); // 9 是最大压缩
imagedestroy($image);
return true;
case 'image/gif':
$image = imagecreatefromgif($sourcePath);
imagegif($image, $destinationPath);
imagedestroy($image);
return true;
case 'image/webp':
// 高版本 PHP 支持
$image = imagecreatefromwebp($sourcePath);
imagewebp($image, $destinationPath, $quality);
imagedestroy($image);
return true;
default:
return false;
}
// 3. 调整尺寸(可选,最有效的压缩方式)
// $newWidth = imagesx($image) * 0.8; // 缩小到80%
// $newHeight = imagesy($image) * 0.8;
// $newImage = imagecreatetruecolor($newWidth, $newHeight);
// imagecopyresampled($newImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, imagesx($image), imagesy($image));
// $image = $newImage;
// 4. 输出并设置质量 (JPEG/WebP)
if ($mime === 'image/jpeg') {
imagejpeg($image, $destinationPath, $quality); // quality 0-100
} elseif ($mime === 'image/webp') {
imagewebp($image, $destinationPath, $quality);
}
// 5. 释放内存
imagedestroy($image);
return true;
}
// 使用示例
compressImageGD('origin.jpg', 'compressed.jpg', 60);
?>
注意:
$quality值越低,文件越小,画质越差,一般 60-80 是个不错的平衡点。- PNG 压缩在 GD 里效果一般,且会损失透明度,如果需要保留透明 PNG,建议用方案二。
使用 Imagick 扩展(推荐,功能强大)
优点: 支持格式多(WebP、HEIC、AVIF),压缩算法更优,支持高级参数(如 strip EXIF、渐进式)。
缺点: 需要服务器安装 imagick 扩展。
核心原理: 利用 ImageMagick 库进行精细化处理。
<?php
function compressImageImagick($sourcePath, $destinationPath, $quality = 75) {
$imagick = new \Imagick(realpath($sourcePath));
// 1. 设定压缩质量 (0-100)
$imagick->setImageCompressionQuality($quality);
// 2. 移除所有 EXIF 数据(相机信息、GPS等),可减少大量体积
$imagick->stripImage();
// 3. 优化图片(针对 JPEG/PNG 的额外无损压缩)
// $imagick->setInterlaceScheme(Imagick::INTERLACE_PLANE); // 渐进式 JPEG
// 4. 调整尺寸(可选)
// $imagick->resizeImage(800, 0, Imagick::FILTER_LANCZOS, 1); // 宽度800,高度自适应
// 5. 如果原图是 PNG,可以转成 JPEG(体积会小很多,但会损失透明背景)
// $imagick->setImageFormat('jpeg');
// $imagick->setImageBackgroundColor('white'); // 设置白色背景
// $imagick = $imagick->flattenImages(); // 合并图层
// 6. 转换为 WebP(强烈推荐,体积小、画质好)
// $imagick->setImageFormat('webp');
// 7. 写入文件
$imagick->writeImage($destinationPath);
$imagick->clear();
return true;
}
// 使用示例
compressImageImagick('origin.png', 'compressed.webp', 80);
?>
优势总结:
stripImage()能去掉大量元数据。- 原生支持 WebP 转换,体积通常比 JPEG 小 25-35%。
- 压缩质量更高,尤其低质量下比 GD 好。
使用第三方库(如 Intervention Image)
优点: 封装了 GD 和 Imagick,代码优雅、跨环境兼容。 缺点: 需要 Composer 安装。
安装(推荐在 Laravel 或 ThinkPHP 项目中使用):
composer require intervention/image
使用示例:
use Intervention\Image\ImageManager;
// 选择驱动(根据服务器环境自动选择 GD 或 Imagick)
$manager = new ImageManager(['driver' => 'gd']);
$image = $manager->make('origin.jpg');
// 压缩并保存
$image->resize(800, null, function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize(); // 不放大
})
->save('compressed.jpg', 75); // 第二个参数是质量
// 转 WebP 保存
$image->encode('webp', 75)->save('compressed.webp');
调用外部 API / 云服务(大规模、高性能)
如果你的项目需要处理海量图片,或者不想占用服务器 CPU,推荐使用云服务:
-
TinyPNG / TinyJPG API (tinify)
- 效果极佳,带有损压缩,视觉无损。
- 安装包:
composer require tinify/tinify - 每月免费 500 张,超出付费。
\Tinify\setKey('YOUR_API_KEY'); $source = \Tinify\fromFile('origin.jpg'); $source->toFile('compressed.jpg'); -
七牛云 / 阿里云 OSS / 腾讯云 COS 的图片处理管道
- 上传后,通过 URL 参数或样式处理(如
?imageMogr2/quality/70)。 - 优点:完全不占用服务器资源,CDN 加速,支持多种裁剪缩放。
- 上传后,通过 URL 参数或样式处理(如
总结建议
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 简单的头像/缩略图压缩 | GD 库 | PHP 自带,无需配置,代码几行搞定。 |
| 高质量、专业级压缩 (WebP) | Imagick | 功能最强,支持格式广,压缩效果最好。 |
| Laravel / 追求代码优雅 | Intervention | 封装好,易读,切换驱动方便。 |
| 服务器性能紧张 / 大规模处理 | 外部 API (TinyPNG) | 节省 CPU,效果极致且视觉无损。 |
| 国内大厂云环境 | OSS / COS 图片处理 | 不占服务器资源,结合 CDN,速度快。 |
最佳实践流程:
- 用户上传图片。
- 限制最大尺寸(比如宽高不超过 1920px,这一步对体积影响最大)。
- 使用 Imagick 或 Intervention 进行压缩,质量设为 80。
- 将图片转为 WebP 格式保存。
- 删除原始文件(或缩小后保存为备份)。
这样可以在肉眼几乎看不出差别的情况下,将图片体积减少 60% - 80%。