PHP 中处理图像的利器 GD库

张开发
2026/4/22 9:11:18 15 分钟阅读

分享文章

PHP 中处理图像的利器 GD库
PHP 中处理图像的利器 GD库在 PHP 开发中GD 库是处理图像的核心利器生成验证码、制作缩略图、添加水印、绘制简单图表…… 这些高频需求都能通过 GD 库轻松实现。开启需修改php.ini取消extensiongdWindows或extensiongd.soLinux前的注释重启 Web 服务即可。GD 库基本操作流程所有 GD 操作都遵循 “创建画布 → 分配颜色 → 绘制内容 → 输出 / 保存 → 销毁资源” 的流程?php// 1. 创建画布宽 400高 200$imageimagecreatetruecolor(400,200);// 2. 分配颜色RGB 值$whiteimagecolorallocate($image,255,255,255);// 白色$blackimagecolorallocate($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()绘制填充椭圆// 创建画布$imageimagecreatetruecolor(400,300);$whiteimagecolorallocate($image,255,255,255);$redimagecolorallocate($image,255,0,0);$blueimagecolorallocate($image,0,0,255);$greenimagecolorallocate($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()更清晰推荐使用。/** * 生成等比例缩略图 * param string $srcPath 原图路径 * param string $destPath 缩略图保存路径 * param int $maxWidth 最大宽度 * param int $maxHeight 最大高度 */functioncreateThumbnail($srcPath,$destPath,$maxWidth200,$maxHeight200){// 获取原图信息list($srcWidth,$srcHeight,$type)getimagesize($srcPath);// 根据图片类型创建画布switch($type){caseIMAGETYPE_JPEG:$srcImageimagecreatefromjpeg($srcPath);break;caseIMAGETYPE_PNG:$srcImageimagecreatefrompng($srcPath);break;default:returnfalse;}// 计算等比例缩放后的尺寸$scalemin($maxWidth/$srcWidth,$maxHeight/$srcHeight);$destWidth$srcWidth*$scale;$destHeight$srcHeight*$scale;// 创建缩略图画布$destImageimagecreatetruecolor($destWidth,$destHeight);// 处理 PNG 透明背景可选若不需要可省略if($typeIMAGETYPE_PNG){$transparentimagecolorallocatealpha($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;}添加水印文字水印/** * 添加文字水印 * 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:$imageimagecreatefromjpeg($srcPath);break;caseIMAGETYPE_PNG:$imageimagecreatefrompng($srcPath);break;default:returnfalse;}// 分配水印颜色半透明白色$watermarkColorimagecolorallocatealpha($image,255,255,255,50);// 50 是透明度0-127越大越透明// 设置字体大小$fontSize20;// 计算文字位置右下角$bboximagettfbbox($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;}图片水印/** * 添加图片水印 * 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:$srcImageimagecreatefromjpeg($srcPath);break;caseIMAGETYPE_PNG:$srcImageimagecreatefrompng($srcPath);break;default:returnfalse;}$wmImageimagecreatefrompng($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 库生成验证码的核心是 “随机字符 干扰线 噪点”。?phpsession_start();// 开启 Session用于保存验证码// 1. 创建画布$width120;$height40;$imageimagecreatetruecolor($width,$height);// 2. 分配颜色$whiteimagecolorallocate($image,255,255,255);$grayimagecolorallocate($image,200,200,200);$darkGrayimagecolorallocate($image,100,100,100);// 3. 填充背景imagefill($image,0,0,$white);// 4. 绘制干扰线3 条for($i0;$i3;$i){$lineColorimagecolorallocate($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($i0;$i50;$i){$dotColorimagecolorallocate($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($i0;$i4;$i){$code.$chars[rand(0,strlen($chars)-1)];}// 保存到 Session用于后续验证$_SESSION[captcha]strtolower($code);// 7. 写入验证码文字$fontSize16;$fontPath./simhei.ttf;// 可选若没有可用 imagestringfor($i0;$i4;$i){$charColorimagecolorallocate($image,rand(0,100),rand(0,100),rand(0,100));$x15$i*25;$yrand(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()。

更多文章