功能说明

本函数支持以图片和文字两种方式为图片添加水印,是网站开发中常用的图片处理功能,特别适用于外贸网站、图片分享网站等需要保护图片版权的场景。

支持格式

  • 目标图片:GIF、PNG、JPG
  • 水印图片:PNG、GIF(支持透明度)
  • 水印文字:支持TrueType字体

完整代码

<?php
function setWater($imgSrc, $markImg, $markText, $TextColor, $markPos, $fontType, $markType)
{
    $srcInfo = @getimagesize($imgSrc);
    if (!$srcInfo) return false;
    
    $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: return false;
    }
    if (!$srcim) return false;
    
    $logow = 0; $logoh = 0;
    
    // 图片水印处理
    if ($markType == "img" && !empty($markImg)) {
        if (!file_exists($markImg)) return false;
        $markImgInfo = @getimagesize($markImg);
        if (!$markImgInfo) return false;
        $markImg_w = $markImgInfo[0];
        $markImg_h = $markImgInfo[1];
        if ($srcImg_w < $markImg_w || $srcImg_h < $markImg_h) return false;
        
        switch ($markImgInfo[2]) {
            case 1: $markim = @imagecreatefromgif($markImg); break;
            case 3: 
                $markim = @imagecreatefrompng($markImg);
                imagealphablending($markim, true);
                imagesavealpha($markim, true);
                break;
            default: return false;
        }
        $logow = $markImg_w;
        $logoh = $markImg_h;
    }
    
    // 文字水印处理
    if ($markType == "text" && !empty($markText)) {
        $fontSize = 16;
        if (!file_exists($fontType)) return false;
        $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]);
    }
    
    if ($markPos == 0) $markPos = rand(1, 9);
    
    // 九宫格坐标计算
    switch ($markPos) {
        case 1: $x = 5; $y = $logoh + 5; break;
        case 2: $x = ($srcImg_w - $logow) / 2; $y = $logoh + 5; break;
        case 3: $x = $srcImg_w - $logow - 5; $y = $logoh + 5; break;
        case 4: $x = 5; $y = ($srcImg_h + $logoh) / 2; break;
        case 5: $x = ($srcImg_w - $logow) / 2; $y = ($srcImg_h + $logoh) / 2; break;
        case 6: $x = $srcImg_w - $logow - 5; $y = ($srcImg_h + $logoh) / 2; break;
        case 7: $x = 5; $y = $srcImg_h - 5; break;
        case 8: $x = ($srcImg_w - $logow) / 2; $y = $srcImg_h - 5; break;
        case 9: $x = $srcImg_w - $logow - 5; $y = $srcImg_h - 5; break;
        default: return false;
    }
    
    // 创建目标图像
    $dst_img = @imagecreatetruecolor($srcImg_w, $srcImg_h);
    
    // PNG透明度处理
    if ($srcInfo[2] == 3) {
        imagealphablending($dst_img, false);
        imagesavealpha($dst_img, true);
        $transparent = imagecolorallocatealpha($dst_img, 0, 0, 0, 127);
        imagefill($dst_img, 0, 0, $transparent);
    }
    
    imagecopy($dst_img, $srcim, 0, 0, 0, 0, $srcImg_w, $srcImg_h);
    
    // 添加图片水印
    if ($markType == "img" && isset($markim)) {
        imagecopy($dst_img, $markim, $x, $y - $logoh, 0, 0, $logow, $logoh);
    }
    
    // 添加文字水印
    if ($markType == "text" && !empty($markText)) {
        $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, 85); break;
        case 3: imagepng($dst_img, $imgSrc); break;
    }
    
    imagedestroy($dst_img);
    if (isset($markim)) imagedestroy($markim);
    imagedestroy($srcim);
    
    return true;
}

参数说明

参数说明示例
$imgSrc目标图片路径"uploads/photo.jpg"
$markImg水印图片(PNG/GIF)"images/logo.png"
$markText水印文字"Copyright 2026"
$TextColor文字颜色(RGB)"255,255,255"
$markPos位置(0=随机,1-9九宫格)5(居中)
$fontTypeTrueType字体路径"fonts/simhei.ttf"
$markType水印类型"img" 或 "text"

水印位置示意图

+-------------------------+
|  1:左上   2:中上   3:右上 |
|                         |
|  4:左中   5:居中   6:右中 |
|                         |
|  7:左下   8:中下   9:右下 |
+-------------------------+
0: 随机位置

使用示例

示例1:添加图片水印

$result = setWater(
    'uploads/product.jpg',    // 目标图片
    'images/watermark.png',  // 水印Logo
    '',                      // 无文字
    '255,255,255',           // 文字颜色
    5,                         // 居中
    '',                      // 字体文件
    'img'                     // 图片模式
);

示例2:添加文字水印

$result = setWater(
    'uploads/photo.jpg',     // 目标图片
    '',                      // 无图片水印
    '© 2026 YBB.Press',    // 水印文字
    '255,255,255',           // 白色文字
    9,                         // 右下角
    'fonts/msyh.ttc',        // 微软雅黑
    'text'                    // 文字模式
);

示例3:批量处理图片

$dir = 'uploads/images/';
$files = glob($dir . '*.{jpg,jpeg,png,gif}', GLOB_BRACE);
foreach ($files as $file) {
    setWater($file, 'images/logo.png', 'YBB.Press', '200,200,200', 0, 'fonts/simhei.ttf', 'img');
}

九宫格位置详解

位置值位置说明坐标计算方式
0随机位置rand(1, 9)
1左上角x=5, y=字体高+5
2顶部居中x=(宽-水印宽)/2, y=字体高+5
3右上角x=宽-水印宽-5, y=字体高+5
4左边居中x=5, y=(高+水印高)/2
5正中心x=(宽-水印宽)/2, y=(高+水印高)/2
6右边居中x=宽-水印宽-5, y=(高+水印高)/2
7左下角x=5, y=高-5
8底部居中x=(宽-水印宽)/2, y=高-5
9右下角x=宽-水印宽-5, y=高-5

优化说明

  • 错误处理增强:添加文件存在性、图像资源验证
  • 透明度支持:正确处理PNG透明背景,避免黑底问题
  • 坐标修正:修正文字水印Y坐标计算,确保完整显示
  • JPG质量参数:imagejpeg添加85%质量,平衡质量与大小
  • 内存管理:及时释放图像资源,避免内存泄漏
  • 代码规范:详细注释,提高可读性和可维护性

环境要求

  • PHP版本:PHP 5.4+(推荐PHP 7.4+或PHP 8.x)
  • GD库:必须启用(编译时添加 --with-gd)
  • FreeType:文字水印需要(--with-freetype-dir)
  • 图像格式:GIF、JPEG、PNG

注意事项

  1. 水印图片建议使用PNG格式(支持透明)
  2. 字体文件需TrueType(.ttf/.ttc),中文字体文件较大
  3. 处理大图注意PHP内存限制,可调整memory_limit
  4. 本函数会覆盖原图,如需保留原图请先备份
  5. 批量生产建议添加延时处理,避免服务器负载过高

常见问题

Q: 文字水印显示乱码怎么办?
A: 确保字体文件支持中文字符,使用UTF-8编码。

Q: 透明PNG水印出现黑底?
A: 需要使用imagesavealpha()函数保留透明度信息。

Q: 图片处理时内存不足?
A: 在脚本开头增加内存限制:ini_set('memory_limit', '256M');


本文来源于NDF俱乐部实践总结,优化整理分享。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部