php代码示例如何实现图片水印_php图片加水印代码示例【示例】

9次阅读

imagecopy()是硬覆盖,imagecopymerge()支持透明度混合;PNG水印配JPG原图需用后者或手动处理alpha;文字水印须用imagettftext()并注意字体路径、编码、坐标等细节。

php代码示例如何实现图片水印_php图片加水印代码示例【示例】

php 使用 imagecopy()imagecopymerge() 添加水印的实质区别

加水印不是简单“贴一张图”,核心在于图层叠加方式。用 imagecopy() 是硬覆盖(不透明粘贴),而 imagecopymerge() 支持透明度混合(第二个参数传 50 表示水印半透明)。若水印 PNG 带 alpha 通道,但目标图是 JPEG,直接 imagecopy() 会丢失透明背景,变成黑底;此时必须先用 imagealphablending($dst, true)imagesavealpha($dst, true) 控制合成行为。

  • 对 JPG 原图 + PNG 水印:优先用 imagecopymerge(),避免手动处理 alpha
  • 需要精确控制文字水印位置或旋转角度:改用 imagettftext(),而非图像叠加
  • 水印图尺寸远大于原图时,imagecopyresized() 可先缩放再贴,否则会截断

文字水印必须设置字体路径和字符编码

imagettftext() 不认相对路径,也不自动识别系统字体。传入的字体文件路径必须是绝对路径(如 /var/www/font/yahei.ttf),且 PHP 进程要有读取权限。中文文字默认按 ISO-8859-1 编码解析,直接传 UTF-8 字符串会乱码或报错 Warning: imagettftext(): Could not read font —— 必须用 mb_convert_encoding($text, 'ISO-8859-1', 'UTF-8') 转换。

  • 测试前先用 file_exists($font_path)is_readable($font_path) 校验字体文件
  • 字号单位是像素,不是 pt;太小(如 6)在高清图上几乎不可见
  • 坐标 (x, y) 是文字基线左下角,不是左上角,y 值需预留行高余量

GD 库未启用或不支持 PNG/JPEG 会导致致命错误

运行时报 Call to undefined function imagecreatefromjpeg(),说明 GD 扩展没开,或编译时没带 JPEG/PNG 支持。ubuntu 下装 php-gd 包后还需确认 gd.jpeg_ignore_warning 配置项为 On(否则损坏的 JPG 会中断脚本);windows 下检查 php.ini 是否启用了 extension=gd,并确认 libpng.dlllibjpeg.dll 在系统 PATH 中。

  • extension_loaded('gd')gd_info() 提前检测,别等执行到 imagecreatefrompng() 才崩
  • 部分共享主机禁用 getimagesize(),可用 finfo_open(FILEINFO_MIME_TYPE) 替代判断 MIME 类型
  • 大图(>5MB)加水印易触发内存超限,加 ini_set('memory_limit', '256M') 并用 imagedestroy() 及时释放资源

透明 PNG 水印在白色背景图上“消失”的原因

不是代码错了,是视觉欺骗:当水印 PNG 的 alpha 通道值全为 0(完全透明),或水印内容本身是白色(#FFFFFF)又叠在白色背景 JPG 上,人眼看不到。调试时临时把目标图背景改成深色(如用 imagefilledrectangle($dst, 0, 0, $dst_w, $dst_h, 0x000000) 填黑),就能立刻验证水印是否真的被绘制出来。

立即学习PHP免费学习笔记(深入)”;

  • imagecolorallocatealpha($dst, 255, 255, 255, 127) 创建半透明白色,比纯白更安全
  • 水印位置建议避开右下角(常被裁剪),改用“居中偏右下 5%”这类动态计算:$x = $dst_w * 0.95 - $water_w
  • 生产环境务必关闭 display_errors,用 error_log() 记录水印失败的具体步骤(比如哪一步 imagecreatefromxxx() 返回 false)
text=ZqhQzanResources