100 lines
3.0 KiB
Python
100 lines
3.0 KiB
Python
import os
|
|
from PIL import Image, ImageDraw, ImageFont
|
|
from config import OUTPUT_DIR, SUPPORTED_INPUT_EXTENSIONS, SUPPORTED_OUTPUT_EXTENSIONS
|
|
|
|
|
|
def load_font(size=40):
|
|
"""根据系统加载合适的字体文件。"""
|
|
candidates = [
|
|
r"C:\Windows\Fonts\msyh.ttc",
|
|
r"C:\Windows\Fonts\simhei.ttf",
|
|
r"C:\Windows\Fonts\simsun.ttc",
|
|
r"C:\Windows\Fonts\arial.ttf",
|
|
]
|
|
for path in candidates:
|
|
if os.path.exists(path):
|
|
return ImageFont.truetype(path, size)
|
|
return ImageFont.load_default()
|
|
|
|
|
|
def watermark_image(input_path, text, output_path=None, output_ext=None):
|
|
"""
|
|
给图片添加水印并保存。
|
|
|
|
Args:
|
|
input_path: 输入图片路径
|
|
text: 水印文字内容
|
|
output_path: 输出路径(不含扩展名),默认在 output/ 目录
|
|
output_ext: 指定输出格式扩展名,如 ".png"、".jpg";为 None 则保持原格式
|
|
Returns:
|
|
最终保存的绝对路径
|
|
"""
|
|
img = Image.open(input_path).convert("RGBA")
|
|
|
|
# 水印图层
|
|
overlay = Image.new("RGBA", img.size, (0, 0, 0, 0))
|
|
draw = ImageDraw.Draw(overlay)
|
|
|
|
font = load_font(48)
|
|
bbox = draw.textbbox((0, 0), text, font=font)
|
|
tw, th = bbox[2] - bbox[0], bbox[3] - bbox[1]
|
|
|
|
x = img.width - tw - 20
|
|
y = img.height - th - 20
|
|
|
|
# 半透明背景
|
|
draw.rounded_rectangle(
|
|
[x - 8, y - 4, x + tw + 8, y + th + 4],
|
|
radius=6,
|
|
fill=(0, 0, 0, 140),
|
|
)
|
|
# 文字
|
|
draw.text((x, y), text, fill=(255, 255, 255, 255), font=font)
|
|
|
|
# 合成
|
|
result = Image.alpha_composite(img, overlay)
|
|
result = result.convert("RGB")
|
|
|
|
# 确定输出路径与格式
|
|
if output_ext is None:
|
|
_, ext = os.path.splitext(input_path)
|
|
output_ext = ext.lower()
|
|
else:
|
|
output_ext = output_ext.lower()
|
|
if output_ext not in SUPPORTED_OUTPUT_EXTENSIONS:
|
|
raise ValueError(f"不支持的输出格式: {output_ext},支持的格式: {SUPPORTED_OUTPUT_EXTENSIONS}")
|
|
|
|
if output_path is None:
|
|
base_name = os.path.basename(input_path)
|
|
name_no_ext = os.path.splitext(base_name)[0]
|
|
out_name = f"{name_no_ext}_watermarked{output_ext}"
|
|
output_path = os.path.join(OUTPUT_DIR, out_name)
|
|
elif not output_path.endswith(output_ext):
|
|
output_path = output_path + output_ext
|
|
|
|
# 保存
|
|
save_kwargs = {}
|
|
if output_ext in (".jpg", ".jpeg"):
|
|
save_kwargs["quality"] = 95
|
|
save_kwargs["optimize"] = True
|
|
elif output_ext == ".png":
|
|
save_kwargs["optimize"] = True
|
|
|
|
result.save(output_path, **save_kwargs)
|
|
return os.path.abspath(output_path)
|
|
|
|
|
|
def increment_count():
|
|
"""已处理图片计数 +1。"""
|
|
count = 0
|
|
if os.path.exists(STATS_FILE):
|
|
with open(STATS_FILE, "r", encoding="utf-8") as f:
|
|
try:
|
|
count = int(f.read().strip())
|
|
except ValueError:
|
|
count = 0
|
|
count += 1
|
|
with open(STATS_FILE, "w", encoding="utf-8") as f:
|
|
f.write(str(count))
|
|
return count
|