php用imagettftext加文字水印需确认字体绝对路径、utf-8编码字体、gd资源未释放;坐标基于基线,须用imagettfbbox计算;开启alpha与抗锯齿;处理exif方向及webp兼容性。

PHP用imagettftext加文字水印前必须确认字体文件路径和编码
很多报错根本不是函数不会用,而是imagettftext找不到字体文件,或传了中文但字体不支持UTF-8。linux下路径区分大小写,windows下常因反斜杠没转义导致Warning: imagettftext(): Could not find/open font。
- 字体路径必须是服务器可读的绝对路径,比如
/var/www/fonts/msyh.ttc,别用相对路径或URL - 中文文字务必用UTF-8编码的字体(如
simhei.ttf、msyh.ttc),普通英文TTF通常不带中文字符集 - 如果源图是GD加载的
$im,确保调用imagettftext前没关闭资源或释放图像 - 文字坐标
$x、$y是基线位置,不是左上角——$y设太小会导致文字被裁掉,建议先用imagefontheight或imagettfbbox测边界
文字水印位置计算要用imagettfbbox,别硬写固定坐标
直接写imagettftext($im, 20, 0, 100, 100, ...)在不同字号/字体下极易错位,尤其右下角水印要适配各种图宽高。
- 用
imagettfbbox获取文字实际包围盒:例如$bbox = imagettfbbox(24, 0, '/fonts/msyh.ttc', '© 2024'); -
$bbox返回8个值,$bbox[2]和$bbox[5]分别是右下角x/y,$bbox[0]和$bbox[1]是左上角x/y,宽度=$bbox[2] - $bbox[0],高度=$bbox[5] - $bbox[1] - 右下角水印示例:
$x = imagesx($im) - ($bbox[2] - $bbox[0]) - 10;,$y = imagesy($im) - $bbox[1] + 10;(注意$bbox[1]是负数,基线偏移)
透明度和抗锯齿需手动开启,GD默认不启用
直接调用imagettftext出来的文字边缘发虚或色块生硬,是因为没设置alpha通道和抗锯齿标志。
- 在
imagecreatetruecolor后立即调用imagealphablending($im, true)和imagesavealpha($im, true) - 颜色要用
imagecolorallocatealpha创建,第4个参数是alpha(0=完全不透明,127=完全透明),比如$white = imagecolorallocatealpha($im, 255, 255, 255, 30); - GD库版本低于2.0.28可能不支持某些TTF特性,遇到文字截断或乱码,先
phpinfo()查gd.version
处理失败时优先检查getimagesize返回值和exif_read_data方向
上传图若含EXIF方向信息(比如手机竖拍),imagecreatefromjpeg加载后可能旋转错位,水印贴到“逻辑顶部”而非“视觉顶部”,看着像跑偏了。
立即学习“PHP免费学习笔记(深入)”;
- 先用
getimagesize($file, $info)检查是否返回false,再确认$info['mime']是否为image/jpeg等合法类型 - 对JPEG图,用
exif_read_data($file)读取Orientation,按值用imagerotate校正(常见值6=顺时针90°,需对应调整水印坐标逻辑) - GD不支持WebP原生文字渲染,若源图是WebP,先转成PNG再操作,否则
imagettftext静默失败
事情说清了就结束。水印最难的从来不是写那几行代码,而是字体路径对不对、坐标算得准不准、图片方向有没有被EXIF偷偷改过。