如何使用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
相关产品推荐
相关产品推荐

