如何在透明图片中添加动态斜向文字水印?现有代码无文字显示
斜向水印不显示问题修复方案
原代码存在几个关键问题导致水印无法显示,逐一修正如下:
问题点及修复说明
- 文字颜色与底图冲突:原底图是白色,水印文字也用白色,完全重叠看不到,改成低透明度灰色(如
(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
相关产品推荐
相关产品推荐

