PHP图像处理与GD库完全指南
GD库基础配置
// 检查GD库是否启用
if (extension_loaded('gd') && function_exists('gd_info')) {
echo "GD库已启用\n";
print_r(gd_info());
} else {
echo "GD库未启用,请在php.ini中启用extension=gd";
}
// 常用配置
ini_set('memory_limit', '256M'); // 处理大图时增加内存限制
ini_set('max_execution_time', 300); // 增加执行时间
创建和操作图像
// 创建空白图像 $width = 400; $height = 300; $image = imagecreatetruecolor($width, $height); // 分配颜色 $white = imagecolorallocate($image, 255, 255, 255); $black = imagecolorallocate($image, 0, 0, 0); $red = imagecolorallocate($image, 255, 0, 0); $green = imagecolorallocate($image, 0, 255, 0); $blue = imagecolorallocate($image, 0, 0, 255); // 填充背景 imagefill($image, 0, 0, $white);
绘制基本图形
// 绘制线条 imageline($image, 0, 0, 400, 300, $black); // 对角线 imageline($image, 400, 0, 0, 300, $red); // 反对角线 // 绘制矩形 imagerectangle($image, 50, 50, 150, 150, $blue); // 空心矩形 imagefilledrectangle($image, 200, 50, 350, 150, $green); // 实心矩形 // 绘制圆形 imageellipse($image, 200, 200, 100, 100, $black); // 空心圆 imagefilledellipse($image, 100, 200, 80, 80, $red); // 实心圆 // 绘制椭圆 imageellipse($image, 300, 200, 120, 60, $blue); // 绘制多边形 $points = [100, 250, 150, 280, 120, 310, 80, 280]; imagepolygon($image, $points, 4, $green); imagefilledpolygon($image, [250, 250, 300, 250, 275, 300], 3, $red); // 绘制弧线 imagearc($image, 350, 250, 80, 50, 0, 180, $black);
文本处理
// 内置字体
$text = "Hello World!";
$font = 5; // 1-5内置字体
imagestring($image, $font, 50, 50, $text, $black);
// 横向文本
imagestringup($image, $font, 400, 200, "垂直文本", $red);
// TrueType字体(支持中文)
$ttfFont = '/path/to/your/font.ttf';
$chineseText = "你好世界!";
imagettftext(
$image, // 图像资源
20, // 字号
0, // 角度
100, // x坐标
100, // y坐标
$blue, // 颜色
$ttfFont, // 字体文件路径
$chineseText // 文本内容
);
// 计算文本尺寸
$bbox = imagettfbbox(20, 0, $ttfFont, $chineseText);
$textWidth = $bbox[2] - $bbox[0];
$textHeight = $bbox[1] - $bbox[7];
图像处理功能
// 从文件加载图像
$sourceImage = imagecreatefromjpeg('source.jpg');
// 其他格式:imagecreatefrompng(), imagecreatefromgif(), imagecreatefromwebp()
// 获取图像信息
$width = imagesx($sourceImage);
$height = imagesy($sourceImage);
// 图像缩放
$newWidth = 200;
$newHeight = 150;
$resizedImage = imagecreatetruecolor($newWidth, $newHeight);
imagecopyresampled(
$resizedImage, // 目标图像
$sourceImage, // 源图像
0, 0, // 目标x,y
0, 0, // 源x,y
$newWidth, // 目标宽度
$newHeight, // 目标高度
$width, // 源宽度
$height // 源高度
);
// 图像裁剪
$cropImage = imagecrop($sourceImage, ['x' => 100, 'y' => 50, 'width' => 300, 'height' => 200]);
// 旋转图像
$rotatedImage = imagerotate($sourceImage, 90, 0);
// 图像水印
$watermark = imagecreatefrompng('watermark.png');
$watermarkWidth = imagesx($watermark);
$watermarkHeight = imagesy($watermark);
imagecopy(
$sourceImage, // 目标图像
$watermark, // 水印图像
$width - $watermarkWidth - 10, // x位置(右下角)
$height - $watermarkHeight - 10, // y位置
0, 0, // 水印起始坐标
$watermarkWidth,
$watermarkHeight
);
图像滤镜和效果
// 灰度化
imagefilter($image, IMG_FILTER_GRAYSCALE);
// 亮度调整
imagefilter($image, IMG_FILTER_BRIGHTNESS, 50); // -255到255
// 对比度
imagefilter($image, IMG_FILTER_CONTRAST, -50); // -100到100
// 浮雕效果
imagefilter($image, IMG_FILTER_EMBOSS);
// 模糊
imagefilter($image, IMG_FILTER_GAUSSIAN_BLUR);
// 边缘检测
imagefilter($image, IMG_FILTER_EDGEDETECT);
// 颜色调整
imagefilter($image, IMG_FILTER_COLORIZE, 100, 0, 0, 0); // 添加红色色调
// 像素化
imagefilter($image, IMG_FILTER_PIXELATE, 10, true);
// 自定义滤镜(锐化)
$sharpenMatrix = [
[0, -1, 0],
[-1, 5, -1],
[0, -1, 0]
];
$divisor = 1;
$offset = 0;
imageconvolution($image, $sharpenMatrix, $divisor, $offset);
输出和保存图像
// 输出到浏览器
header('Content-Type: image/jpeg');
imagejpeg($image, null, 90); // 质量0-100
header('Content-Type: image/png');
imagepng($image, null, 9); // 压缩级别0-9
header('Content-Type: image/gif');
imagegif($image);
header('Content-Type: image/webp');
imagewebp($image, null, 80); // 质量0-100
// 保存到文件
imagejpeg($image, 'output.jpg', 85);
imagepng($image, 'output.png', 9);
imagegif($image, 'output.gif');
imagewebp($image, 'output.webp', 80);
完整示例:图片处理类
class ImageProcessor {
private $image;
private $width;
private $height;
private $type;
public function __construct($file) {
$info = getimagesize($file);
$this->width = $info[0];
$this->height = $info[1];
$this->type = $info[2];
switch ($this->type) {
case IMAGETYPE_JPEG:
$this->image = imagecreatefromjpeg($file);
break;
case IMAGETYPE_PNG:
$this->image = imagecreatefrompng($file);
break;
case IMAGETYPE_GIF:
$this->image = imagecreatefromgif($file);
break;
case IMAGETYPE_WEBP:
$this->image = imagecreatefromwebp($file);
break;
default:
throw new Exception('不支持的图片格式');
}
}
public function resize($width, $height, $crop = false) {
if ($crop) {
$ratio = max($width / $this->width, $height / $this->height);
$newWidth = $this->width * $ratio;
$newHeight = $this->height * $ratio;
} else {
$ratio = min($width / $this->width, $height / $this->height);
$newWidth = $this->width * $ratio;
$newHeight = $this->height * $ratio;
}
$newImage = imagecreatetruecolor($width, $height);
// 处理透明度
if ($this->type == IMAGETYPE_PNG || $this->type == IMAGETYPE_GIF) {
imagealphablending($newImage, false);
imagesavealpha($newImage, true);
}
imagecopyresampled(
$newImage, $this->image,
0, 0,
$crop ? ($this->width - $newWidth) / 2 : 0,
$crop ? ($this->height - $newHeight) / 2 : 0,
$width, $height,
$newWidth, $newHeight
);
$this->image = $newImage;
$this->width = $width;
$this->height = $height;
return $this;
}
public function addWatermark($watermarkFile, $position = 'bottom-right', $opacity = 50) {
$watermark = imagecreatefrompng($watermarkFile);
$wmWidth = imagesx($watermark);
$wmHeight = imagesy($watermark);
// 计算位置
switch ($position) {
case 'top-left':
$x = 10;
$y = 10;
break;
case 'top-right':
$x = $this->width - $wmWidth - 10;
$y = 10;
break;
case 'bottom-left':
$x = 10;
$y = $this->height - $wmHeight - 10;
break;
default: // bottom-right
$x = $this->width - $wmWidth - 10;
$y = $this->height - $wmHeight - 10;
}
// 设置透明度
imagecopymerge($this->image, $watermark, $x, $y, 0, 0, $wmWidth, $wmHeight, $opacity);
imagedestroy($watermark);
return $this;
}
public function addText($text, $font, $size = 20, $color = [255, 255, 255], $position = 'center') {
$textColor = imagecolorallocate($this->image, $color[0], $color[1], $color[2]);
$bbox = imagettfbbox($size, 0, $font, $text);
$textWidth = $bbox[2] - $bbox[0];
$textHeight = $bbox[1] - $bbox[7];
switch ($position) {
case 'top':
$x = ($this->width - $textWidth) / 2;
$y = $textHeight + 10;
break;
case 'center':
$x = ($this->width - $textWidth) / 2;
$y = ($this->height + $textHeight) / 2;
break;
default:
$x = 10;
$y = $this->height - 10;
}
imagettftext($this->image, $size, 0, $x, $y, $textColor, $font, $text);
return $this;
}
public function save($path, $quality = 80) {
$extension = strtolower(pathinfo($path, PATHINFO_EXTENSION));
switch ($extension) {
case 'jpg':
case 'jpeg':
imagejpeg($this->image, $path, $quality);
break;
case 'png':
imagepng($this->image, $path, round((100 - $quality) / 11.1));
break;
case 'gif':
imagegif($this->image, $path);
break;
case 'webp':
imagewebp($this->image, $path, $quality);
break;
default:
throw new Exception('不支持的输出格式');
}
}
public function __destruct() {
if ($this->image) {
imagedestroy($this->image);
}
}
}
// 使用示例
try {
$processor = new ImageProcessor('input.jpg');
$processor
->resize(800, 600, true) // 裁剪缩放
->addWatermark('watermark.png', 'bottom-right', 50)
->addText('© 2024', '/path/to/font.ttf', 14, [255, 255, 255], 'bottom-left')
->save('output.jpg', 85);
echo "图片处理完成!";
} catch (Exception $e) {
echo "错误:" . $e->getMessage();
}
性能优化建议
// 1. 使用内存优化
$image = imagecreatetruecolor($width, $height);
imagepalettetotruecolor($image); // 提升色彩质量
// 2. 渐进式JPEG
imageinterlace($image, true); // 开启渐进式加载
// 3. 批量处理时释放内存
if (isset($image)) {
imagedestroy($image);
unset($image);
}
// 4. 使用适当的压缩级别
imagepng($image, null, 6); // 平衡质量和文件大小
imagejpeg($image, null, 80); // 常用质量设置
// 5. 启用输出缓冲
ob_start();
imagepng($image);
$imageData = ob_get_clean();
echo $imageData;
常见问题和解决方案
// 1. 内存不足错误
ini_set('memory_limit', '512M');
// 2. 图片不能包含中文路径
$file = mb_convert_encoding($file, 'GBK', 'UTF-8');
// 3. 透明PNG处理
imagealphablending($image, false);
imagesavealpha($image, true);
// 4. 处理大图片
class LargeImageHandler {
public static function handle($source, $maxWidth = 2000) {
$info = getimagesize($source);
if ($info[0] > $maxWidth) {
$ratio = $maxWidth / $info[0];
$newWidth = $maxWidth;
$newHeight = $info[1] * $ratio;
$image = imagecreatefromstring(file_get_contents($source));
$resized = imagecreatetruecolor($newWidth, $newHeight);
imagecopyresampled($resized, $image, 0, 0, 0, 0, $newWidth, $newHeight, $info[0], $info[1]);
return $resized;
}
return imagecreatefromstring(file_get_contents($source));
}
}
GD库是PHP处理图像最常用的扩展,掌握这些功能可以满足大部分Web开发中的图像处理需求,对于更高级的需求(如复杂的滤镜、AI处理等),可以考虑使用ImageMagick扩展。
