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

📅 发布时间:2026/9/28 3:29:16
深入详解PHP中图像处理的利器GD库的操作流程
在 PHP 开发中GD 库是处理图像的核心利器生成验证码、制作缩略图、添加水印、绘制简单图表…… 这些高频需求都能通过 GD 库轻松实现。开启需修改php.ini取消extensiongdWindows或extensiongd.soLinux前的注释重启 Web 服务即可。GD 库基本操作流程所有 GD 操作都遵循 “创建画布 → 分配颜色 → 绘制内容 → 输出 / 保存 → 销毁资源” 的流程123456789101112131415161718192021?php// 1. 创建画布宽 400高 200$image imagecreatetruecolor(400, 200);// 2. 分配颜色RGB 值$white imagecolorallocate($image, 255, 255, 255);// 白色$black imagecolorallocate($image, 0, 0, 0);// 黑色// 3. 填充背景色imagefill($image, 0, 0,$white);// 4. 绘制内容比如写一行字imagestring($image, 5, 100, 90,Hello GD!,$black);// 5. 输出图像或保存到文件header(Content-Type: image/png);// 告诉浏览器输出的是 PNG 图片imagepng($image);// 6. 销毁资源释放内存imagedestroy($image);?常用功能绘制基本图形GD 库支持绘制直线、矩形、圆形、椭圆等基础图形适合制作简单图表或标记。函数说明imageline()绘制直线imagerectangle()绘制矩形边框imagefilledrectangle()绘制填充矩形imageellipse()绘制椭圆圆形是椭圆的特例imagefilledellipse()绘制填充椭圆1234567891011121314151617181920212223242526// 创建画布$image imagecreatetruecolor(400, 300);$white imagecolorallocate($image, 255, 255, 255);$red imagecolorallocate($image, 255, 0, 0);$blue imagecolorallocate($image, 0, 0, 255);$green imagecolorallocate($image, 0, 255, 0);// 填充白色背景imagefill($image, 0, 0,$white);// 1. 绘制红色直线从 x1,y1 到 x2,y2imageline($image, 50, 50, 350, 50,$red);// 2. 绘制蓝色矩形边框x1,y1 左上角x2,y2 右下角imagerectangle($image, 50, 80, 150, 180,$blue);// 3. 绘制绿色填充矩形imagefilledrectangle($image, 200, 80, 350, 180,$green);// 4. 绘制红色填充圆形圆心 x,y宽高相同即为圆imagefilledellipse($image, 200, 240, 80, 80,$red);// 输出图像header(Content-Type: image/png);imagepng($image);imagedestroy($image);生成缩略图网站上传图片时生成缩略图是刚需。GD 库通过imagecopyresampled()实现高质量缩放。imagecreatefromjpeg()/imagecreatefrompng()从现有图片创建画布资源。imagecopyresampled()重采样复制图像比imagecopyresized()更清晰推荐使用。12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061/*** 生成等比例缩略图* param string $srcPath 原图路径* param string $destPath 缩略图保存路径* param int $maxWidth 最大宽度* param int $maxHeight 最大高度*/functioncreateThumbnail($srcPath,$destPath,$maxWidth 200,$maxHeight 200) {// 获取原图信息list($srcWidth,$srcHeight,$type) getimagesize($srcPath);// 根据图片类型创建画布switch($type) {caseIMAGETYPE_JPEG:$srcImage imagecreatefromjpeg($srcPath);break;caseIMAGETYPE_PNG:$srcImage imagecreatefrompng($srcPath);break;default:returnfalse;}// 计算等比例缩放后的尺寸$scale min($maxWidth/$srcWidth,$maxHeight/$srcHeight);$destWidth$srcWidth*$scale;$destHeight$srcHeight*$scale;// 创建缩略图画布$destImage imagecreatetruecolor($destWidth,$destHeight);// 处理 PNG 透明背景可选若不需要可省略if($type IMAGETYPE_PNG) {$transparent imagecolorallocatealpha($destImage, 255, 255, 255, 127);imagefill($destImage, 0, 0,$transparent);imagesavealpha($destImage, true);}// 重采样复制核心步骤imagecopyresampled($destImage,$srcImage,// 目标画布、源画布0, 0, 0, 0,// 目标 x,y、源 x,y$destWidth,$destHeight,// 目标宽高$srcWidth,$srcHeight// 源宽高);// 保存缩略图switch($type) {caseIMAGETYPE_JPEG:imagejpeg($destImage,$destPath, 90);// 90 是 JPEG 质量break;caseIMAGETYPE_PNG:imagepng($destImage,$destPath);break;}// 销毁资源imagedestroy($srcImage);imagedestroy($destImage);returntrue;}添加水印文字水印1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950/*** 添加文字水印* param string $srcPath 原图路径* param string $text 水印文字* param string $fontPath 字体文件路径需支持中文比如 simhei.ttf*/functionaddTextWatermark($srcPath,$text,$fontPath./simhei.ttf) {// 获取原图信息list($width,$height,$type) getimagesize($srcPath);switch($type) {caseIMAGETYPE_JPEG:$image imagecreatefromjpeg($srcPath);break;caseIMAGETYPE_PNG:$image imagecreatefrompng($srcPath);break;default:returnfalse;}// 分配水印颜色半透明白色$watermarkColor imagecolorallocatealpha($image, 255, 255, 255, 50);// 50 是透明度0-127越大越透明// 设置字体大小$fontSize 20;// 计算文字位置右下角$bbox imagettfbbox($fontSize, 0,$fontPath,$text);$textWidth$bbox[2] -$bbox[0];$textHeight$bbox[1] -$bbox[7];$x$width-$textWidth- 20;// 距离右边 20px$y$height-$textHeight- 20;// 距离下边 20px// 写入文字使用 TrueType 字体支持中文imagettftext($image,$fontSize, 0,$x,$y,$watermarkColor,$fontPath,$text);// 保存图片$destPath./watermark_text.jpg;switch($type) {caseIMAGETYPE_JPEG:imagejpeg($image,$destPath, 90);break;caseIMAGETYPE_PNG:imagepng($image,$destPath);break;}imagedestroy($image);return$destPath;}图片水印123456789101112131415161718192021222324252627282930313233343536373839404142434445/*** 添加图片水印* param string $srcPath 原图路径* param string $watermarkPath 水印图片路径建议 PNG 透明图*/functionaddImageWatermark($srcPath,$watermarkPath) {// 获取原图和水印图信息list($srcWidth,$srcHeight,$srcType) getimagesize($srcPath);list($wmWidth,$wmHeight,$wmType) getimagesize($watermarkPath);// 创建画布switch($srcType) {caseIMAGETYPE_JPEG:$srcImage imagecreatefromjpeg($srcPath);break;caseIMAGETYPE_PNG:$srcImage imagecreatefrompng($srcPath);break;default:returnfalse;}$wmImage imagecreatefrompng($watermarkPath);// 假设水印是 PNG// 计算水印位置右下角$x$srcWidth-$wmWidth- 20;$y$srcHeight-$wmHeight- 20;// 合并水印保留 PNG 透明度imagecopy($srcImage,$wmImage,$x,$y, 0, 0,$wmWidth,$wmHeight);// 保存图片$destPath./watermark_image.jpg;switch($srcType) {caseIMAGETYPE_JPEG:imagejpeg($srcImage,$destPath, 90);break;caseIMAGETYPE_PNG:imagepng($srcImage,$destPath);break;}imagedestroy($srcImage);imagedestroy($wmImage);return$destPath;}生成验证码验证码是防止恶意注册、刷接口的常用手段GD 库生成验证码的核心是 “随机字符 干扰线 噪点”。1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253?phpsession_start();// 开启 Session用于保存验证码// 1. 创建画布$width 120;$height 40;$image imagecreatetruecolor($width,$height);// 2. 分配颜色$white imagecolorallocate($image, 255, 255, 255);$gray imagecolorallocate($image, 200, 200, 200);$darkGray imagecolorallocate($image, 100, 100, 100);// 3. 填充背景imagefill($image, 0, 0,$white);// 4. 绘制干扰线3 条for($i 0;$i 3;$i) {$lineColor imagecolorallocate($image, rand(100, 200), rand(100, 200), rand(100, 200));imageline($image, rand(0,$width), rand(0,$height), rand(0,$width), rand(0,$height),$lineColor);}// 5. 绘制噪点50 个for($i 0;$i 50;$i) {$dotColor imagecolorallocate($image, rand(50, 150), rand(50, 150), rand(50, 150));imagesetpixel($image, rand(0,$width), rand(0,$height),$dotColor);}// 6. 生成随机验证码$chars23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ;// 去掉易混淆的 0、1、O、l$code;for($i 0;$i 4;$i) {$code.$chars[rand(0,strlen($chars) - 1)];}// 保存到 Session用于后续验证$_SESSION[captcha] strtolower($code);// 7. 写入验证码文字$fontSize 16;$fontPath./simhei.ttf;// 可选若没有可用 imagestringfor($i 0;$i 4;$i) {$charColor imagecolorallocate($image, rand(0, 100), rand(0, 100), rand(0, 100));$x 15 $i* 25;$y rand(25, 35);imagettftext($image,$fontSize, rand(-10, 10),$x,$y,$charColor,$fontPath,$code[$i]);}// 8. 输出图像header(Content-Type: image/png);imagepng($image);imagedestroy($image);?注意事项记得销毁资源每次 GD 操作后务必用imagedestroy()销毁图像资源避免内存泄漏。输出前无任何输出在header(Content-Type: image/png)前不能有任何 HTML 标签、空格或换行否则会导致图像无法显示。处理大图片注意内存处理高分辨率图片时可能会超出 PHP 内存限制可在代码开头临时调整ini_set(memory_limit, 256M);。中文支持用 TrueType 字体imagestring()不支持中文需用imagettftext()配合.ttf字体文件如simhei.ttf黑体。优先使用imagecopyresampled()缩放图片时imagecopyresampled()会进行重采样生成的缩略图更清晰不要用imagecopyresized()。