使用Python OpenCV为多张不同尺寸图片左下角添加透明水印求助
解决OpenCV添加自适应透明水印到左下角方案
原有代码问题说明
- 第一段代码问题:
- 读取水印时未使用
cv2.IMREAD_UNCHANGED参数,丢失了透明通道,导致透明效果失效 - ROI区域固定取左上角
[0:rows, 0:cols],因此水印固定在左上角 - 基于灰度阈值生成mask的方式误差大,无法适配复杂透明效果的水印
- 读取水印时未使用
- 第二段代码问题:
- 硬编码坐标
num1、num2,无法适配不同尺寸的目标图 - 未做水印等比缩放,不同尺寸目标图会出现水印过大/过小、变形的问题
- 硬编码坐标
完整实现代码
import cv2 import numpy as np def add_watermark(target_img_path, watermark_path, output_path, wm_width_ratio=0.2, padding=10): """ 给目标图添加左下角透明水印 :param target_img_path: 目标图片路径 :param watermark_path: 带透明通道的水印图片路径 :param output_path: 输出图片路径 :param wm_width_ratio: 水印宽度占目标图宽度的比例,默认0.2即20%,可自行调整 :param padding: 水印距离底部和左侧的边距,默认10像素,可自行调整 """ # 读取目标图和水印图,水印图保留alpha通道 target = cv2.imread(target_img_path) wm = cv2.imread(watermark_path, cv2.IMREAD_UNCHANGED) if wm.shape[2] !=4: raise Exception("水印图片不包含透明通道,请检查") t_h, t_w = target.shape[:2] wm_h, wm_w = wm.shape[:2] # 等比缩放水印,避免变形 new_wm_w = int(t_w * wm_width_ratio) new_wm_h = int(new_wm_w * wm_h / wm_w) wm_resized = cv2.resize(wm, (new_wm_w, new_wm_h), interpolation=cv2.INTER_AREA) # 计算水印在左下角的坐标,动态适配不同尺寸目标图 x = padding y = t_h - new_wm_h - padding # 提取水印的alpha通道作为掩膜 wm_alpha = wm_resized[:, :, 3] / 255.0 target_alpha = 1.0 - wm_alpha # 取出目标图对应的ROI区域 roi = target[y:y+new_wm_h, x:x+new_wm_w] # 融合水印和ROI区域,保留透明效果 for c in range(3): roi[:, :, c] = (wm_alpha * wm_resized[:, :, c] + target_alpha * roi[:, :, c]).astype(np.uint8) # 把融合后的区域放回原图 target[y:y+new_wm_h, x:x+new_wm_w] = roi cv2.imwrite(output_path, target) # 调用示例 if __name__ == "__main__": add_watermark("my_image.png", "my_watermark.png", "output_with_watermark.png")
参数调整说明
- 若要修改水印大小,调整
wm_width_ratio参数即可,比如设置为0.3代表水印宽度为目标图宽度的30% - 若要调整水印和边缘的距离,修改
padding参数即可 - 批量处理多张图片时,遍历目标图片路径循环调用
add_watermark函数即可
内容的提问来源于stack exchange,提问作者shahab-qazavi
相关产品推荐
相关产品推荐

