TP6需安装topthink/think-image扩展并使用\think\image\Image类,水印须用32位PNG、位置常量及alpha()链式调用,文字水印依赖绝对路径TTF字体与FreeType支持,GD驱动有局限,可切换Imagick。

TP6 默认不带水印能力,不装 topthink/think-image 就调用 \Think\Image 必报 Class not found 错误。
装扩展前先确认类名和命名空间
TP6 已移除内置图像处理类,\Think\Image 是 TP5 的旧路径,现在正确类是 \think\image\Image(注意小写 think,不是大写 Think)。直接 new \Think\Image() 会立刻失败,哪怕你以前在 TP5 写熟了。
- 执行
composer require topthink/think-image安装扩展 - 装完若仍报错,跑一次
composer dump-autoload刷新自动加载缓存 - 代码里必须用
use \think\image\Image;或完整写\think\image\Image::open(...)
water() 方法的坑:位置常量、透明度、水印图格式
water() 看似简单,但三个参数全踩错就白忙活:位置常量写错、透明度没设、水印图本身不带 alpha 通道,结果全是黑底或白边。
- 位置别硬写数字,用常量:
\think\image\Image::WATER_SOUTHEAST(右下角),不是IMAGE_WATER_SOUTHEAST(那是 TP5) - 水印 PNG 必须是 32 位(含透明通道),用 Photoshop 导出时勾选「透明度」,GIMP 要选「Save background color as alpha」
- 加透明度要链式调用:
->alpha(70),否则默认不透明;alpha()必须在water()之后、save()之前 - 水印图尺寸建议 ≤ 原图宽高的 1/4,否则 GD 内存溢出报
Allowed memory size exhausted
文字水印慎用 text():字体路径和中文乱码是高频雷区
text() 不像 water() 那样“开箱即用”,它极度依赖字体文件路径和 PHP 的 FreeType 支持。本地能跑,上线就乱码,十有八九是字体路径错了或服务器没装 freetype 扩展。
立即学习“PHP免费学习笔记(深入)”;
- 字体路径必须是绝对路径,推荐用
__DIR__ . '/fonts/simhei.ttf',别用getcwd() . '/public/font/xxx.ttf'(getcwd()在 CLI 和 FPM 下行为不一致) - 中文必须用 TTF 字体,
imagestring()不支持;且 PHP 编译时得带--with-freetype,否则imagettftext()直接失败 - 颜色参数是十六进制字符串如
'#ffffff',不是数组;透明度靠alpha参数控制(0–100),不是 CSS 那套 rgba - 右下角定位别手算:
$x = $image->width() - $image->fontWidth($font, $size) - 10,fontWidth()才准,别用 strlen
GD 驱动限制明显,别指望 GIF 动画或高质量缩放
TP6 的 think-image 默认只启用 GD 驱动,而 GD 对 GIF 动画、高倍数缩放、精细抗锯齿支持极差。想切 Imagick,不能改配置,必须实例化时指定:
- 用 GD(默认):
$img = new \think\image\Image(\think\image\Image::DRIVER_GD, $srcPath) - 用 Imagick:
$img = new \think\image\Image(\think\image\Image::DRIVER_IMAGICK, $srcPath),前提是服务器已装 imagick 扩展 - GD 处理 PNG 透明水印时,
background()和alpha()行为不一致——alpha()控制水印透明度,background()只影响THUMB_FILLED模式下的填充色,别混用
最常被忽略的是水印图本身的导出设置和 GD 的内存限制——哪怕代码全对,水印图是 24 位 PNG 或服务器 memory_limit=64M,一样失败。



















