结论:imagecopymerge不支持PNG alpha通道,会导致水印发灰或白边;必须用imagecopy配合imagealphablending(false)和imagesavealpha(true)组合才能正确保留透明度,且目标图与源图均需启用该设置。

直接说结论:PHP 的 imagecopymerge 或 imagealphablending + imagecopy 是实现头像拼图打卡最稳妥的方案,不是 GD 库所有图像混合函数都支持透明通道,用错就糊成一片色块。
为什么不用 imagecopymerge 直接覆盖?
它看似简单——把头像按指定位置、透明度贴到模板上,但问题在于:imagecopymerge 只做“像素级加权平均”,不识别 PNG 的 alpha 通道。哪怕你的头像带透明背景,一合并就变灰边或白底。
- 仅适用于纯 RGB 模板 + 无透明需求的 JPG 头像
- 透明度参数(第 8 个参数)是全局整数(0–100),无法保留源图原始透明层次
- 如果模板本身含半透明区域(比如渐变遮罩),结果会严重失真
imagealphablending 和 imagesavealpha 必须成对出现
这是保住 PNG 透明底的关键组合。单独开 imagealphablending 会让新绘制内容“融入”背景色,反而吃掉透明;必须配合 imagesavealpha 锁住 alpha 通道。
- 加载头像后立刻调用:
imagealphablending($avatar, false)+imagesavealpha($avatar, true) - 目标画布(模板)也要同样设置,否则
imagecopy时 alpha 信息被丢弃 - 注意顺序:先关 blending,再开 savealpha,反了无效
缩放+居中裁切头像前,先确认原始尺寸比
打卡模板通常要求头像为圆形或正方形区域,用户上传图却五花八门。直接 imagecopyresampled 拉伸会导致脸变形。
立即学习“PHP免费学习笔记(深入)”;
- 用
getimagesize()先读宽高,判断是横图($width > $height)还是竖图 - 按短边裁切中心区域,再缩放到目标尺寸,避免黑边或拉伸
- 示例裁切逻辑:
$min = min($w, $h); $x = ($w - $min) / 2; $y = ($h - $min) / 2;
真正麻烦的不是合成动作本身,而是不同来源头像的色彩空间(sRGB vs Adobe RGB)、嵌入 ICC 配置文件、以及 PHP-GD 编译时是否启用了 libpng 支持——这些不会报错,但会让同一张图在本地和线上服务器渲染出微妙色差。



















