图像添加水印代码
1、自动文字生成版
# add_watermark.py
from PIL import Image, ImageDraw, ImageFont
import os
import random
class WaterMark():
def __init__(self,
font_folder="",
font_size=20,
):
super().__init__()
# 创建字体对象
self.font_dict = {}
self.font_path_dict = {}
for root, dirs, files in os.walk(font_folder):
for file in files:
if file.lower().endswith(('ttf', '.ttc')):
file_path = os.path.join(root, file)
file_name = os.path.splitext(os.path.basename(file_path))[0]
self.font_dict[file_name] = ImageFont.truetype(file_path, font_size)
self.font_path_dict[file_name] = file_path
# print(self.font_dict)
# print(self.font_path_dict)
self.font_size = font_size
def add(self,
# image_path,
image,
watermark_text="None Text!",
watermark_mode='1',
watermark_height=None,
position_x=0,
position_y=0,
font_name='arial',
font_size=20,
# font_color="black",
):
# 打开原始图片
# image = Image.open(image_path)
# 计算文字尺寸
dummy_image = Image.new('RGB', (1, 1))
dummy_draw = ImageDraw.Draw(dummy_image)
font = self.font_dict[font_name] if font_size == self.font_size else ImageFont.truetype(self.font_path_dict[font_name], font_size)
self.text_bbox = dummy_draw.textbbox((0, 0), watermark_text, font=font)
# print(text_bbox)
self.text_width = self.text_bbox[2] - self.text_bbox[0]
self.text_height = self.text_bbox[3] - self.text_bbox[1]
# text_width, text_height = dummy_draw.textsize(watermark_text, font=font)
# print("text_bbox:", self.text_bbox, "text_width:", self.text_width, "text_height:", self.text_height)
if watermark_mode == '2': # 'overlay'
result = self.overlay(
image=image,
watermark_text=watermark_text,
position_x=position_x,
position_y=position_y,
font=font,
font_color="white",
)
elif watermark_mode == '1': # 'concatenate'
result = self.concatenate(
image=image,
watermark_text=watermark_text,
watermark_height=watermark_height,
position_x=position_x,
position_y=position_y,
font=font,
font_color="black",
)
else:
# 随机选择并调用一个函数
chosen_mode = random.choice(['1', '2'])
# print("chosen_mode:", chosen_mode)
if chosen_mode == '2':
position_x = 20
position_y = -10
elif chosen_mode == '1':
position_x = 20
position_y = watermark_height//2 - self.text_height//2 if watermark_height else self.text_height
# print(watermark_height, position_y)
result = self.add(
# image_path=image_path,
image=image,
watermark_text=watermark_text,
watermark_mode=chosen_mode,
watermark_height=watermark_height,
position_x=position_x,
position_y=position_y,
font_name=font_name,
font_size=font_size,
)
return result
def overlay(self,
image,
watermark_text="None Text!",
position_x=0,
position_y=0,
font=None,
font_color="white",
):
# 叠加模式
if position_y >= image.height - self.text_height:
position_y = image.height - self.text_height
elif self.text_height - image.height <= position_y <= 0:
position_y = image.height - self.text_height + position_y
elif position_y <= self.text_height - image.height:
position_y = 0
# print("position_x:", position_x, "position_y:", position_y)
logo_image = Image.open('./watermarks/AIGClogo.png').convert("RGBA")
new_text_height = int(self.text_height * 1.1)
new_width = int(logo_image.width * new_text_height / logo_image.height)
logo_image_resized = logo_image.resize((new_width, new_text_height), )
# logo_image_resized = logo_image.resize((new_width, new_text_height), Image.NEAREST)
# 创建一个新的透明图层,尺寸与原始图像相同
watermark_background = Image.new('RGBA', image.size, (0, 0, 0, 0))
# 在背景上绘制文本
draw = ImageDraw.Draw(watermark_background)
watermark_background.paste(image, (0, 0))
draw.text((position_x, position_y-self.text_bbox[1]), watermark_text, font=font, fill=font_color)
# 将 "AIGC" 图像粘贴到文字水印图层上
AIGC_position = (position_x + self.text_width + 5, position_y - int(self.text_height * 0.05))
watermark_background.paste(logo_image_resized, AIGC_position, logo_image_resized)
# 将文字图层叠加到原图上
# watermarked = Image.alpha_composite(image.convert('RGBA'), watermark_background) # 白色文字线条会变淡变细。
return watermark_background.convert('RGB')
def concatenate(self,
image,
watermark_text="None Text!",
watermark_height=None,
position_x=0,
position_y=0,
font=None,
font_color="black",
):
# 拼接模式
if watermark_height is None:
watermark_height = self.text_height * 3
greybg_image = Image.open('./watermarks/greybg.png').convert("RGBA")
# watermark_height = min(watermark_height, greybg_image.height)
# print("watermark_height:", watermark_height)
if position_y >= watermark_height - self.text_height:
position_y = watermark_height - self.text_height
elif self.text_height - watermark_height <= position_y <= 0:
position_y = watermark_height - self.text_height + position_y
elif position_y <= self.text_height - watermark_height:
position_y = 0
# print("position_x:", position_x, "position_y:", position_y)
# greybg_new_width = int(greybg_image.width * watermark_height / greybg_image.height)
# greybg_image_resized = greybg_image.resize((greybg_new_width, watermark_height), )
greybg_image_resized = greybg_image.resize((image.width//2, watermark_height), )
logo_image = Image.open('./watermarks/reddot.png').convert("RGBA")
logo_new_width = int(logo_image.width * self.text_height / logo_image.height)
logo_image_resized = logo_image.resize((logo_new_width//2, self.text_height//2))
# 创建文字背景图层
watermark_background = Image.new('RGB', (image.width, watermark_height), "white")
watermark_background.paste(greybg_image_resized, (watermark_background.width - greybg_image_resized.width, watermark_background.height - greybg_image_resized.height), greybg_image_resized)
# 在背景上绘制文本
draw = ImageDraw.Draw(watermark_background)
draw.text((position_x, position_y-self.text_bbox[1]), watermark_text, font=font, fill=font_color)
## 计算文字尺寸
dummy_image = Image.new('RGB', (1, 1))
dummy_draw = ImageDraw.Draw(dummy_image)
tmp_text_bbox = dummy_draw.textbbox((0, 0), "AIGC Portrait", font=font)
tmp_text_width = tmp_text_bbox[2] - tmp_text_bbox[0]
tmp_text_height = tmp_text_bbox[3] - tmp_text_bbox[1]
draw.text((image.width - tmp_text_width -30, position_y-self.text_bbox[1]), "AIGC Portrait", font=font, fill="black")
AIGC_position = (position_x + self.text_width + 5, position_y + self.text_height//4)
watermark_background.paste(logo_image_resized, AIGC_position, logo_image_resized)
# 将文字图层拼接到原图下方
watermarked = Image.new('RGB', (image.width, image.height + watermark_height))
watermarked.paste(image, (0, 0))
watermarked.paste(watermark_background, (0, image.height))
return watermarked.convert('RGB')
# 使用示例
if __name__ == "__main__":
wm = WaterMark(font_folder="./fonts", font_size=20,)
watermarked_image = wm.add(image_path="20240613-112009.jpg",
watermark_text="AI_CV算法组测试",
watermark_mode='2',
watermark_height=None,
position_x=20,
position_y=-10,
font_name='STZHONGS',
font_size=25,)
# 保存结果
watermarked_image.save("watermarked_image112.jpg")
1、水印贴图版
# add_watermark.py
from PIL import Image
import os
import random
class WaterMark():
def __init__(self,
watermark_folder="",
):
super().__init__()
self.watermark_1 = {}
self.watermark_2 = {}
if watermark_folder:
for root, dirs, files in os.walk(watermark_folder):
image_list = []
for file in files:
if file.lower().endswith(('.jpg', )):
file_path = os.path.join(root, file)
file_name = os.path.splitext(os.path.basename(file_path))[0]
self.watermark_1[file_name] = Image.open(file_path)
if file.lower().endswith(('.png', )):
file_path = os.path.join(root, file)
file_name = os.path.splitext(os.path.basename(file_path))[0]
self.watermark_2[file_name] = Image.open(file_path)
# print(self.watermark_1)
# print(self.watermark_2)
def add(self,
image,
watermark_name="aaa_30_bb_5g",
watermark_mode='1',
position_x=None,
position_y=None,
):
# print(image, watermark_name, watermark_mode, position_x, position_y)
if watermark_mode == '2': # 'overlay'
result = self.overlay(
image=image,
watermark_name=watermark_name,
position_x=position_x,
position_y=position_y,
)
elif watermark_mode == '1': # 'concatenate'
result = self.concatenate(
image=image,
watermark_name=watermark_name,
)
else:
# 随机选择并调用一个函数
chosen_mode = random.choice(['1', '2'])
result = self.add(
image=image,
watermark_name=watermark_name,
watermark_mode=chosen_mode,
position_x=position_x,
position_y=position_y,
)
return result
def overlay(self,
image,
watermark_name=None,
position_x=None,
position_y=None,
):
# 叠加模式
if watermark_name and watermark_name in self.watermark_2 and self.watermark_2[watermark_name]:
logo_image_resized = self.watermark_2[watermark_name]
# logo_image = self.watermark_2[watermark_name]
# new_width = image.width // 4
# new_height = int(logo_image.height * new_width / logo_image.width)
# logo_image_resized = logo_image.resize((new_width, new_height), )
# 创建一个新的透明图层,尺寸与原始图像相同
watermark_background = Image.new('RGBA', image.size, (0, 0, 0, 0))
watermark_background.paste(image, (0, 0))
# 将 "AIGC" 图像粘贴到文字水印图层上
if position_x is None:
position_x = 0
if position_y is None:
position_y = image.height - logo_image_resized.height
AIGC_position = (position_x, position_y)
watermark_background.paste(logo_image_resized, AIGC_position, logo_image_resized)
return watermark_background.convert('RGB')
else:
print("Please check watermark file!")
return image
def concatenate(self,
image,
watermark_name=None,
):
# 拼接模式
if watermark_name and watermark_name in self.watermark_1 and self.watermark_1[watermark_name]:
logo_image = self.watermark_1[watermark_name]
new_width = image.width
new_height = int(logo_image.height * new_width / logo_image.width)
logo_image_resized = logo_image.resize((new_width, new_height), )
# 创建一个新的透明图层,尺寸与原始图像相同
# watermark_background = Image.new('RGBA', image.size, (0, 0, 0, 0))
watermark_background = Image.new('RGB', (image.width, image.height + new_height))
watermark_background.paste(image, (0, 0))
# 将 "AIGC" 图像粘贴到文字水印图层上
AIGC_position = (0, image.height)
# watermark_background.paste(logo_image_resized, AIGC_position, logo_image_resized)
watermark_background.paste(logo_image_resized, AIGC_position)
return watermark_background.convert('RGB')
else:
print("Please check watermark file!")
return image
# 使用示例
if __name__ == "__main__":
wm = WaterMark(watermark_folder="./watermarks",)
image = Image.open("image.png", )
watermarked_image = wm.add(image=image,
watermark_name="xxx_aigc",
watermark_mode='2',
position_x=None,
position_y=None,
)
# 保存结果
watermarked_image.save("watermarked_image.jpg")