当前位置:首页 > PHP教程 > php图像处理 > 列表

深入详解PHP中图像处理的利器GD库的操作流程

发布:smiling 来源: PHP粉丝网  添加日期:2026-07-15 17:35:34 浏览: 评论:0 

在 PHP 开发中,GD 库是处理图像的核心利器:生成验证码、制作缩略图、添加水印、绘制简单图表…… 这些高频需求都能通过 GD 库轻松实现。

开启需修改 php.ini,取消 extension=gd(Windows)或 extension=gd.so(Linux)前的注释,重启 Web 服务即可。

GD 库基本操作流程

所有 GD 操作都遵循 “创建画布 → 分配颜色 → 绘制内容 → 输出 / 保存 → 销毁资源” 的流程:

  1. <?php 
  2. // 1. 创建画布(宽 400,高 200) 
  3. $image = imagecreatetruecolor(400, 200); 
  4.   
  5. // 2. 分配颜色(RGB 值) 
  6. $white = imagecolorallocate($image, 255, 255, 255); // 白色 
  7. $black = imagecolorallocate($image, 0, 0, 0);       // 黑色 
  8.   
  9. // 3. 填充背景色 
  10. imagefill($image, 0, 0, $white); 
  11.   
  12. // 4. 绘制内容(比如写一行字) 
  13. imagestring($image, 5, 100, 90, 'Hello GD!'$black); 
  14.   
  15. // 5. 输出图像(或保存到文件) 
  16. header('Content-Type: image/png'); // 告诉浏览器输出的是 PNG 图片 
  17. imagepng($image); 
  18.   
  19. // 6. 销毁资源,释放内存 
  20. imagedestroy($image); 
  21. ?> 

常用功能

绘制基本图形

GD 库支持绘制直线、矩形、圆形、椭圆等基础图形,适合制作简单图表或标记。

函数 说明

imageline() 绘制直线

imagerectangle() 绘制矩形(边框)

imagefilledrectangle() 绘制填充矩形

imageellipse() 绘制椭圆(圆形是椭圆的特例)

imagefilledellipse() 绘制填充椭圆

  1. // 创建画布 
  2. $image = imagecreatetruecolor(400, 300); 
  3. $white = imagecolorallocate($image, 255, 255, 255); 
  4. $red = imagecolorallocate($image, 255, 0, 0); 
  5. $blue = imagecolorallocate($image, 0, 0, 255); 
  6. $green = imagecolorallocate($image, 0, 255, 0); 
  7.   
  8. // 填充白色背景 
  9. imagefill($image, 0, 0, $white); 
  10.   
  11. // 1. 绘制红色直线(从 x1,y1 到 x2,y2) 
  12. imageline($image, 50, 50, 350, 50, $red); 
  13.   
  14. // 2. 绘制蓝色矩形边框(x1,y1 左上角,x2,y2 右下角) 
  15. imagerectangle($image, 50, 80, 150, 180, $blue); 
  16.   
  17. // 3. 绘制绿色填充矩形 
  18. imagefilledrectangle($image, 200, 80, 350, 180, $green); 
  19.   
  20. // 4. 绘制红色填充圆形(圆心 x,y,宽高相同即为圆) 
  21. imagefilledellipse($image, 200, 240, 80, 80, $red); 
  22.   
  23. // 输出图像 
  24. header('Content-Type: image/png'); 
  25. imagepng($image); 
  26. imagedestroy($image); 

生成缩略图

网站上传图片时,生成缩略图是刚需。GD 库通过 imagecopyresampled() 实现高质量缩放。

imagecreatefromjpeg() / imagecreatefrompng():从现有图片创建画布资源。

imagecopyresampled():重采样复制图像(比 imagecopyresized() 更清晰,推荐使用)。

  1. /** 
  2.  * 生成等比例缩略图 
  3.  * @param string $srcPath 原图路径 
  4.  * @param string $destPath 缩略图保存路径 
  5.  * @param int $maxWidth 最大宽度 
  6.  * @param int $maxHeight 最大高度 
  7.  */ 
  8. function createThumbnail($srcPath$destPath$maxWidth = 200, $maxHeight = 200) { 
  9.     // 获取原图信息 
  10.     list($srcWidth$srcHeight$type) = getimagesize($srcPath); 
  11.       
  12.     // 根据图片类型创建画布 
  13.     switch ($type) { 
  14.         case IMAGETYPE_JPEG: 
  15.             $srcImage = imagecreatefromjpeg($srcPath); 
  16.             break
  17.         case IMAGETYPE_PNG: 
  18.             $srcImage = imagecreatefrompng($srcPath); 
  19.             break
  20.         default
  21.             return false; 
  22.     } 
  23.       
  24.     // 计算等比例缩放后的尺寸 
  25.     $scale = min($maxWidth / $srcWidth$maxHeight / $srcHeight); 
  26.     $destWidth = $srcWidth * $scale
  27.     $destHeight = $srcHeight * $scale
  28.       
  29.     // 创建缩略图画布 
  30.     $destImage = imagecreatetruecolor($destWidth$destHeight); 
  31.       
  32.     // 处理 PNG 透明背景(可选,若不需要可省略) 
  33.     if ($type == IMAGETYPE_PNG) { 
  34.         $transparent = imagecolorallocatealpha($destImage, 255, 255, 255, 127); 
  35.         imagefill($destImage, 0, 0, $transparent); 
  36.         imagesavealpha($destImage, true); 
  37.     } 
  38.       
  39.     // 重采样复制(核心步骤) 
  40.     imagecopyresampled( 
  41.         $destImage$srcImage// 目标画布、源画布 
  42.         0, 0, 0, 0,            // 目标 x,y、源 x,y 
  43.         $destWidth$destHeight,// 目标宽高 
  44.         $srcWidth$srcHeight   // 源宽高 
  45.     ); 
  46.       
  47.     // 保存缩略图 
  48.     switch ($type) { 
  49.         case IMAGETYPE_JPEG: 
  50.             imagejpeg($destImage$destPath, 90); // 90 是 JPEG 质量 
  51.             break
  52.         case IMAGETYPE_PNG: 
  53.             imagepng($destImage$destPath); 
  54.             break
  55.     } 
  56.       
  57.     // 销毁资源 
  58.     imagedestroy($srcImage); 
  59.     imagedestroy($destImage); 
  60.     return true; 

添加水印

文字水印

  1. /** 
  2.  * 添加文字水印 
  3.  * @param string $srcPath 原图路径 
  4.  * @param string $text 水印文字 
  5.  * @param string $fontPath 字体文件路径(需支持中文,比如 simhei.ttf) 
  6.  */ 
  7. function addTextWatermark($srcPath$text$fontPath = './simhei.ttf') { 
  8.     // 获取原图信息 
  9.     list($width$height$type) = getimagesize($srcPath); 
  10.     switch ($type) { 
  11.         case IMAGETYPE_JPEG: 
  12.             $image = imagecreatefromjpeg($srcPath); 
  13.             break
  14.         case IMAGETYPE_PNG: 
  15.             $image = imagecreatefrompng($srcPath); 
  16.             break
  17.         default
  18.             return false; 
  19.     } 
  20.       
  21.     // 分配水印颜色(半透明白色) 
  22.     $watermarkColor = imagecolorallocatealpha($image, 255, 255, 255, 50); // 50 是透明度(0-127,越大越透明) 
  23.       
  24.     // 设置字体大小 
  25.     $fontSize = 20; 
  26.       
  27.     // 计算文字位置(右下角) 
  28.     $bbox = imagettfbbox($fontSize, 0, $fontPath$text); 
  29.     $textWidth = $bbox[2] - $bbox[0]; 
  30.     $textHeight = $bbox[1] - $bbox[7]; 
  31.     $x = $width - $textWidth - 20; // 距离右边 20px 
  32.     $y = $height - $textHeight - 20; // 距离下边 20px 
  33.       
  34.     // 写入文字(使用 TrueType 字体,支持中文) 
  35.     imagettftext($image$fontSize, 0, $x$y$watermarkColor$fontPath$text); 
  36.       
  37.     // 保存图片 
  38.     $destPath = './watermark_text.jpg'
  39.     switch ($type) { 
  40.         case IMAGETYPE_JPEG: 
  41.             imagejpeg($image$destPath, 90); 
  42.             break
  43.         case IMAGETYPE_PNG: 
  44.             imagepng($image$destPath); 
  45.             break
  46.     } 
  47.       
  48.     imagedestroy($image); 
  49.     return $destPath

图片水印

  1. /** 
  2.  * 添加图片水印 
  3.  * @param string $srcPath 原图路径 
  4.  * @param string $watermarkPath 水印图片路径(建议 PNG 透明图) 
  5.  */ 
  6. function addImageWatermark($srcPath$watermarkPath) { 
  7.     // 获取原图和水印图信息 
  8.     list($srcWidth$srcHeight$srcType) = getimagesize($srcPath); 
  9.     list($wmWidth$wmHeight$wmType) = getimagesize($watermarkPath); 
  10.       
  11.     // 创建画布 
  12.     switch ($srcType) { 
  13.         case IMAGETYPE_JPEG: 
  14.             $srcImage = imagecreatefromjpeg($srcPath); 
  15.             break
  16.         case IMAGETYPE_PNG: 
  17.             $srcImage = imagecreatefrompng($srcPath); 
  18.             break
  19.         default
  20.             return false; 
  21.     } 
  22.     $wmImage = imagecreatefrompng($watermarkPath); // 假设水印是 PNG 
  23.       
  24.     // 计算水印位置(右下角) 
  25.     $x = $srcWidth - $wmWidth - 20; 
  26.     $y = $srcHeight - $wmHeight - 20; 
  27.       
  28.     // 合并水印(保留 PNG 透明度) 
  29.     imagecopy($srcImage$wmImage$x$y, 0, 0, $wmWidth$wmHeight); 
  30.       
  31.     // 保存图片 
  32.     $destPath = './watermark_image.jpg'
  33.     switch ($srcType) { 
  34.         case IMAGETYPE_JPEG: 
  35.             imagejpeg($srcImage$destPath, 90); 
  36.             break
  37.         case IMAGETYPE_PNG: 
  38.             imagepng($srcImage$destPath); 
  39.             break
  40.     } 
  41.       
  42.     imagedestroy($srcImage); 
  43.     imagedestroy($wmImage); 
  44.     return $destPath

生成验证码

验证码是防止恶意注册、刷接口的常用手段,GD 库生成验证码的核心是 “随机字符 + 干扰线 + 噪点”。

  1. <?php 
  2. session_start(); // 开启 Session,用于保存验证码 
  3.   
  4. // 1. 创建画布 
  5. $width = 120; 
  6. $height = 40; 
  7. $image = imagecreatetruecolor($width$height); 
  8.   
  9. // 2. 分配颜色 
  10. $white = imagecolorallocate($image, 255, 255, 255); 
  11. $gray = imagecolorallocate($image, 200, 200, 200); 
  12. $darkGray = imagecolorallocate($image, 100, 100, 100); 
  13.   
  14. // 3. 填充背景 
  15. imagefill($image, 0, 0, $white); 
  16.   
  17. // 4. 绘制干扰线(3 条) 
  18. for ($i = 0; $i < 3; $i++) { 
  19.     $lineColor = imagecolorallocate($image, rand(100, 200), rand(100, 200), rand(100, 200)); 
  20.     imageline($image, rand(0, $width), rand(0, $height), rand(0, $width), rand(0, $height), $lineColor); 
  21.   
  22. // 5. 绘制噪点(50 个) 
  23. for ($i = 0; $i < 50; $i++) { 
  24.     $dotColor = imagecolorallocate($image, rand(50, 150), rand(50, 150), rand(50, 150)); 
  25.     imagesetpixel($image, rand(0, $width), rand(0, $height), $dotColor); 
  26.   
  27. // 6. 生成随机验证码 
  28. $chars = '23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'// 去掉易混淆的 0、1、O、l 
  29. $code = ''
  30. for ($i = 0; $i < 4; $i++) { 
  31.     $code .= $chars[rand(0, strlen($chars) - 1)]; 
  32.   
  33. // 保存到 Session,用于后续验证 
  34. $_SESSION['captcha'] = strtolower($code); 
  35.   
  36. // 7. 写入验证码文字 
  37. $fontSize = 16; 
  38. $fontPath = './simhei.ttf'// 可选,若没有可用 imagestring 
  39. for ($i = 0; $i < 4; $i++) { 
  40.     $charColor = imagecolorallocate($image, rand(0, 100), rand(0, 100), rand(0, 100)); 
  41.     $x = 15 + $i * 25; 
  42.     $y = rand(25, 35); 
  43.     imagettftext($image$fontSize, rand(-10, 10), $x$y$charColor$fontPath$code[$i]); 
  44.   
  45. // 8. 输出图像 
  46. header('Content-Type: image/png'); 
  47. imagepng($image); 
  48. imagedestroy($image); 
  49. ?> 

注意事项

记得销毁资源:每次 GD 操作后,务必用 imagedestroy() 销毁图像资源,避免内存泄漏。

输出前无任何输出:在 header('Content-Type: image/png') 前,不能有任何 HTML 标签、空格或换行,否则会导致图像无法显示。

处理大图片注意内存:处理高分辨率图片时,可能会超出 PHP 内存限制,可在代码开头临时调整:ini_set('memory_limit', '256M');。

中文支持用 TrueType 字体:imagestring() 不支持中文,需用 imagettftext() 配合 .ttf 字体文件(如 simhei.ttf 黑体)。

优先使用 imagecopyresampled() :缩放图片时,imagecopyresampled() 会进行重采样,生成的缩略图更清晰,不要用 imagecopyresized()。

Tags: PHP图像处理 PHP GD库

分享到: