You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用PHP为用户上传的图片添加水印 附现有业务代码参考

PHP+WordPress环境下图片自动加水印实现方案

一、核心实现逻辑

你当前使用的是WordPress的Houzez主题,直接挂钩WordPress原生的附件上传钩子即可实现上传即打水印的效果,无需改动你现有的图片展示逻辑:

  • 图片上传到服务器后,在存入媒体库之前自动触发水印处理逻辑
  • 水印直接合并到原图中,后续所有尺寸的缩略图都会自动携带水印

二、PHP水印处理与定位核心函数

常用基础函数

  • 尺寸获取:getimagesize() 可读取原图、水印logo的宽度、高度、文件格式,是计算水印位置的核心依赖
  • 图片资源创建:根据图片格式分别使用imagecreatefromjpeg()、imagecreatefrompng()、imagecreatefromwebp(),如果水印是透明PNG需要额外开启alpha通道处理
  • 水印合并:imagecopymerge() 支持设置水印透明度,是最常用的合并函数;如果不需要透明度可以用imagecopy()

水印位置计算方法

你可以根据需要自定义位置,通用计算逻辑如下(默认设置10px的边距避免贴边):

// 先获取尺寸
list($src_w, $src_h) = getimagesize('原图路径');
list($logo_w, $logo_h) = getimagesize('水印logo路径');
$padding = 10; // 边距可自定义

// 1. 右下角(最常用)
$pos_x = $src_w - $logo_w - $padding;
$pos_y = $src_h - $logo_h - $padding;

// 2. 右上角
// $pos_x = $src_w - $logo_w - $padding;
// $pos_y = $padding;

// 3. 左下角
// $pos_x = $padding;
// $pos_y = $src_h - $logo_h - $padding;

// 4. 左上角
// $pos_x = $padding;
// $pos_y = $padding;

// 5. 居中
// $pos_x = ($src_w - $logo_w) / 2;
// $pos_y = ($src_h - $logo_h) / 2;

三、适配你场景的完整代码实现

直接把以下代码加到你主题的functions.php文件中即可生效:

/**
 * 给上传的图片自动添加水印
 */
function houzez_add_watermark_to_uploaded_image($upload) {
    // 只处理图片类型文件
    $img_mimes = ['image/jpeg', 'image/png', 'image/webp'];
    if (!in_array($upload['type'], $img_mimes)) {
        return $upload;
    }

    $src_path = $upload['file'];
    $logo_path = get_stylesheet_directory() . '/images/watermark-logo.png'; // 替换为你的水印logo实际路径

    // 校验水印文件存在
    if (!file_exists($logo_path)) {
        return $upload;
    }

    // 获取原图和水印尺寸
    list($src_w, $src_h, $src_type) = getimagesize($src_path);
    list($logo_w, $logo_h) = getimagesize($logo_path);

    // 创建原图资源
    switch ($src_type) {
        case IMAGETYPE_JPEG:
            $src_img = imagecreatefromjpeg($src_path);
            break;
        case IMAGETYPE_PNG:
            $src_img = imagecreatefrompng($src_path);
            break;
        case IMAGETYPE_WEBP:
            $src_img = imagecreatefromwebp($src_path);
            break;
        default:
            return $upload;
    }

    // 创建水印资源,保留透明通道
    $logo_img = imagecreatefrompng($logo_path);
    imagealphablending($logo_img, true);
    imagesavealpha($logo_img, true);

    // 计算水印位置(这里用右下角,可按上面的方法替换其他位置)
    $padding = 10;
    $pos_x = $src_w - $logo_w - $padding;
    $pos_y = $src_h - $logo_h - $padding;

    // 合并水印,透明度设为70(0-100可调,数值越大越不透明)
    imagecopymerge($src_img, $logo_img, $pos_x, $pos_y, 0, 0, $logo_w, $logo_h, 70);

    // 保存合并后的图片覆盖原图
    switch ($src_type) {
        case IMAGETYPE_JPEG:
            imagejpeg($src_img, $src_path, 90); // 90是jpg质量,可调
            break;
        case IMAGETYPE_PNG:
            imagepng($src_img, $src_path, 8); // 8是png压缩级别,可调
            break;
        case IMAGETYPE_WEBP:
            imagewebp($src_img, $src_path, 90);
            break;
    }

    // 销毁资源释放内存
    imagedestroy($src_img);
    imagedestroy($logo_img);

    return $upload;
}
add_filter('wp_handle_upload', 'houzez_add_watermark_to_uploaded_image');

四、现有代码适配说明

你贴出的是已上传图片的前端展示代码,不需要做任何修改,只要加了上面的钩子,新上传的图片会自动携带水印,原有已上传的图片不会受影响。

注意事项

  • 请提前把水印logo上传到主题目录下的对应路径,替换代码里的$logo_path变量值
  • 如果需要保留无水印的原图,可修改保存逻辑把带水印的图存为新文件,不要覆盖原图
  • 水印尺寸建议提前调整到合适大小,避免在小图上显示过大

内容的提问来源于stack exchange,提问作者Suhail Dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 23:54:04