PHP使用GD库给图片添加文字水印的多种实现方案

栗子
栗子
发布时间:2026-10-13 | 5人浏览过
原创

在PHP开发中,利用GD库动态处理图片是常见需求。本文整理了使用imagestring(像素字体)和imagettftext(TrueType字体)给图片添加文字水印的代码示例,包括基础面向过程写法、面向对象类封装、高灵活性多参数脚本以及远程图片处理流程,供不同场景选用。

1. 面向过程的直接写法

这是最基础的实现方式,通过判断文件扩展名调用对应的imagecreatefrom...系列函数加载图片,写入内存后执行输出并销毁资源。适合简单的单次处理任务。

$src = '001.png';
$info = getimagesize($src);
$type = image_type_to_extension($info[2], false);
$fun = "imagecreatefrom{$type}";
$image = $fun('001.png');

// 定义颜色和字体内容
$col = imagecolorallocatealpha($image, 255, 255, 255, 50);
$content = 'HelloWorld';

// 在坐标(20,30)处绘制文字
imagestring($image, 5, 20, 30, $content, $col);

header('Content-type: ' . $info['mime']);
$func = "image{$type}";
$func($image);
imagedestroy($image);
  • 注意事项:imagestring仅支持系统内置的像素级字体(大小1-5),无法使用自定义TTF字体文件。

2. 面向对象封装:Image_class

将图片处理逻辑封装为Image_class类,通过构造函数自动加载图片,提供fontMark方法进行文字渲染,适合需要在项目中复用且需要保持代码整洁的场景。

class Image_class {
  private $image;
  private $info;

  function __construct($src){
    $info = getimagesize($src);
    $type = image_type_to_extension($info[2], false);
    $this->info = $info;
    $this->info['type'] = $type;
    $fun = "imagecreatefrom" . $type;
    $this->image = $fun($src);
  }

  public function fontMark($fontsize, $x, $y, $color, $text){
    // 注意:这里仍然使用imagestring,所以$fontsize只能是1-5
    $col = imagecolorallocatealpha($this->image, $color[0], $color[1], $color[2], $color[3]);
    imagestring($this->image, $fontsize, $x, $y, $text, $col);
  }

  public function show(){
    header('Content-type: ' . $this->info['mime']);
    $fun = 'image' . $this->info['type'];
    $fun($this->image);
  }

  function __destruct(){
    imagedestroy($this->image);
  }
}

// 实例化并使用
$obj = new Image_class('001.png');
// 第4个参数为RGBA数组,注意透明通道范围0-127
$obj->fontMark(5, 20, 30, array(255, 255, 255, 60), 'Hello World');
$obj->show();

3. 支持图文水印及多位置的通用函数

该方案提供了高度灵活的配置项。支持设置图片水印或文字水印,允许指定9个固定的相对位置(如居中、角落等)以及随机位置。若需使用文字水印,必须引入imagettftext并配合字体文件(.ttf)。

function setWater($imgSrc, $markImg, $markText, $TextColor, $markPos, $fontType, $markType) {
    $srcInfo = @getimagesize($imgSrc);
    $srcImg_w = $srcInfo[0];
    $srcImg_h = $srcInfo[1];

    switch ($srcInfo[2]) {
        case 1: $srcim = imagecreatefromgif($imgSrc); break;
        case 2: $srcim = imagecreatefromjpeg($imgSrc); break;
        case 3: $srcim = imagecreatefrompng($imgSrc); break;
        default: die("不支持的图片文件类型"); exit;
    }

    if (!strcmp($markType, "img")) {
        // 图片水印逻辑
        $markImgInfo = @getimagesize($markImg);
        $markImg_w = $markImgInfo[0];
        $markImg_h = $markImgInfo[1];
        switch ($markImgInfo[2]) {
            case 1: $markim = imagecreatefromgif($markImg); break;
            case 2: $markim = imagecreatefromjpeg($markImg); break;
            case 3: $markim = imagecreatefrompng($markImg); break;
            default: die("不支持的水印图片类型"); exit;
        }
        $logow = $markImg_w;
        $logoh = $markImg_h;
    } else {
        // 文字水印逻辑
        $fontSize = 16;
        $box = @imagettfbbox($fontSize, 0, $fontType, $markText);
        $logow = max($box[2], $box[4]) - min($box[0], $box[6]);
        $logoh = max($box[1], $box[3]) - min($box[5], $box[7]);
    }

    // 定位计算... (此处省略详细的位置switch计算代码,见源码中的switch($markPos)部分)
    $x = ...; $y = ...; // 根据markPos值计算

    $dst_img = @imagecreatetruecolor($srcImg_w, $srcImg_h);
    imagecopy($dst_img, $srcim, 0, 0, 0, 0, $srcImg_w, $srcImg_h);

    if (!strcmp($markType, "img")) {
        imagecopy($dst_img, $markim, $x, $y, 0, 0, $logow, $logoh);
        imagedestroy($markim);
    } else {
        $rgb = explode(',', $TextColor);
        $color = imagecolorallocate($dst_img, $rgb[0], $rgb[1], $rgb[2]);
        imagettftext($dst_img, $fontSize, 0, $x, $y, $color, $fontType, $markText);
    }

    // 保存结果至源文件路径(原脚本会覆盖原始图片)
    switch ($srcInfo[2]) { 
        case 1: imagegif($dst_img, $imgSrc); break;
        case 2: imagejpeg($dst_img, $imgSrc); break;
        case 3: imagepng($dst_img, $imgSrc); break;
    }
    imagedestroy($dst_img);
    imagedestroy($srcim);
}

参数说明

  • $markType: 'img'表示图片水印,'text'表示文字水印。
  • $markPos: 水印位置,取值为1~8代表固定方位(顶部左/中/右,左侧中,中心,右侧中,底部左/中/右)。若传0,则自动随机选取1~9中的一个。
  • 风险提醒:上述脚本最后阶段直接将结果imagepng/jpg/gif写回$imgSrc路径,这意味着原始图片会被覆盖。生产环境中建议先备份或传入不同的保存路径。

4. 基于URL的图片流处理

如果需要处理的图片来自网络链接,可以使用file_get_contents获取数据流,并通过imagecreatefromstring创建图像资源。这对于从外部接口获取图片并打标的场景非常实用。

<?php
$dst_path = 'http://example.com/sample.jpg'; // 替换为目标URL
$dst = imagecreatefromstring(file_get_contents($dst_path));

// 配置字体和颜色
$font = './t1.ttf';
$black = imagecolorallocate($dst, 0, 0, 0);

// 核心:使用 imagettftext 进行精确渲染
imagefttext($dst, 20, 0, 10, 30, $black, $font, 'Hello world!');

// 输出对应格式到浏览器
list($dst_w,$dst_h,$dst_type) = getimagesize($dst_path);
switch($dst_type){
  case 1: header("content-type:image/gif"); imagegif($dst); break;
  case 2: header("content-type:image/jpeg"); imagejpeg($dst); break;
  case 3: header("content-type:image/png"); imagepng($dst); break;
}
imagedestroy($dst);
?
以上就是使用PHP GD库给图片添加文字水印的详细内容,更多关于PHP图像处理与水印功能的资料请关注本站其它相关文章!
相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表