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

如何在透明图片中添加动态斜向文字水印?现有代码无文字显示

斜向水印不显示问题修复方案

原代码存在几个关键问题导致水印无法显示,逐一修正如下:

问题点及修复说明

  • 文字颜色与底图冲突:原底图是白色,水印文字也用白色,完全重叠看不到,改成低透明度灰色(如(128,128,128,128))才能显现。
  • 旋转后尺寸未适配:图像旋转45度后会超出原尺寸,直接粘贴只会显示左上角部分,需裁剪回原底图尺寸并居中对齐。
  • alpha_composite未生效:该方法返回新的合成图像,原对象不会自动更新,必须重新赋值给watermark。
  • textsize已废弃:PIL现在用textbbox替代textsize来获取文本的宽高。
  • 初始绘制坐标错误:原循环里的坐标会让文字超出初始watermark范围,调整为从斜向起始位置开始绘制。

修正后的完整代码

from PIL import Image, ImageDraw, ImageFont

# 创建白色底图(如果是透明底图,把"RGB"改成"RGBA",背景设为(0,0,0,0))
img = Image.new("RGB", (500, 500), (255, 255, 255))
width, height = img.size

# 创建透明水印画布
watermark = Image.new("RGBA", (width, height), (0, 0, 0, 0))
draw = ImageDraw.Draw(watermark)

# 加载字体,注意字体路径要正确,Windows下可直接用"arial.ttf",Linux/macOS可能需要指定路径
try:
    font = ImageFont.truetype("arial.ttf", 24)
except IOError:
    # fallback到默认字体
    font = ImageFont.load_default(size=24)

text = "Your Text"
# 用textbbox获取文本宽高,textbbox返回(left, top, right, bottom),宽=right-left,高=bottom-top
bbox = draw.textbbox((0,0), text, font=font)
text_width = bbox[2] - bbox[0]
text_height = bbox[3] - bbox[1]

# 计算斜向重复次数,确保覆盖整个对角线
diagonal_len = int((width ** 2 + height ** 2) ** 0.5)
num_repetitions = int(diagonal_len / text_width) + 2

# 调整绘制坐标,让文字从左上角斜向开始排列
for i in range(-num_repetitions, num_repetitions):
    x = i * text_width
    y = -x + text_height  # 调整y坐标,让文字斜向分布
    draw.text((x, y), text, font=font, fill=(128, 128, 128, 128))

# 旋转水印,expand=True会自动适配旋转后的尺寸
watermark_rotated = watermark.rotate(45, expand=True)

# 裁剪旋转后的水印,使其与原底图尺寸一致并居中
rot_w, rot_h = watermark_rotated.size
crop_x = (rot_w - width) // 2
crop_y = (rot_h - height) // 2
watermark_cropped = watermark_rotated.crop((crop_x, crop_y, crop_x + width, crop_y + height))

# 添加额外的透明文字(可选)
overlay = Image.new("RGBA", (width, height), (0, 0, 0, 0))
draw_overlay = ImageDraw.Draw(overlay)
draw_overlay.text((50, 50), "Your Transparent Text", font=font, fill=(128, 128, 128, 128))

# 合成水印和额外文字,必须重新赋值
watermark_final = Image.alpha_composite(watermark_cropped, overlay)

# 把水印合成到底图上,如果底图是RGBA透明图,用alpha_composite更合适
if img.mode == "RGB":
    # RGB底图需要转成RGBA再合成,再转回RGB
    img_rgba = img.convert("RGBA")
    img_rgba.alpha_composite(watermark_final)
    img_final = img_rgba.convert("RGB")
else:
    img_final = Image.alpha_composite(img, watermark_final)

img_final.save("watermarked_image.png")

额外说明

  • 如果你的底图是透明图,把创建底图的代码改成img = Image.new("RGBA", (500, 500), (0,0,0,0))即可。
  • 字体路径如果报错,替换成系统中存在的字体路径,比如Linux下的"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"。

内容的提问来源于stack exchange,提问作者Md Jewele Islam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 13:18:09